javascript 模拟html元素滚动条 jscroll
create()方法用户调整创建带有自定义滚动条的元素整体结构,首先通过创建了wrapper元素,用于包装会出现滚动条的元素elem和滚动条可滚动的区域元素list以及滚动条元素s。通过从出现滚动条元素设置的自定义属性data-width、data-height分别设置wrapper元素的宽度和高度。通过scrollbarHeight()方法计算得到了滚动条元素显示的高度,整体结构不算复杂。创建自定义滚动条整体结构之后是为滚动条元素s和滚动条可到达区域元素list添加事件处理,通过regEvent()方法实现。 //计算滚动条的高度scrollbarHeight: function(elem, height) { var value = elem.scrollHeight; return (height / value) * height } scrollbarHeight()方法通过简单的数学计算返回滚动条元素应该显示的高度。 initEvent: function() {var that = this, _default, elem, top, min, max, prev, parent, sbody, unit; //滚动条滚动 squid.on(document, 'mousemove', function(event) { elem = that.scrolling.elem if(elem !== null) { squid.addClass(elem, 'scrolling') top = event.clientY - that.scrolling.diffy parent = that.ie6 ? elem.parentNode.parentNode : elem.parentNode min = that.limits[elem].min max = that.limits[elem].max prev = parent.previousSibling sbody = prev.tagName.toLowerCase() === 'div' ? prev : prev.previousSibling _default = parseInt(sbody['data-height'] || sbody.getAttribute('data-height'), 10) unit = (sbody.scrollHeight - _default) / max squid.addClass(sbody.parentNode, 'unselectable') if(top < min) { top = min }else if(top > max) { top = max } elem.style.top = top + 'px' that.doScroll(sbody, top * unit) } }) //滚动结束 squid.on(document, 'mouseup', function(event) { elem = that.scrolling.elem if(elem) { prev = that.ie6 ? elem.parentNode.parentNode.previousSibling : elem.parentNode.previousSibling sbody = prev.tagName.toLowerCase() === 'div' ? prev : prev.previousSibling squid.removeClass(sbody.parentNode, 'unselectable') } that.scrolling.elem = null that.scrolling.diffy = 0 }) } initEvent()方法实现了为document元素添加mousemove和mouseup事件,mousemove实现了在拖动滚动条元素滚动时查看的内容跟随变化。代码首先判断当前是否有拖动滚动条查看内容的操作,如果有就计算滚动条被拖动到的位置,然后计算查看内容应该到的地方。代码里对ie6的判断,是因为引入的PIE.htc文件破坏了原有的结构(为了实现跨浏览器下显示效果的一致,付出太大了!!!)。mouseup事件处理程序实现了清除上次操作的滚动条元素。 //添加滚动条事件regEvent: function(elem) { var that = this, sbody = elem.firstChild, list = sbody.nextSibling, //滚动条元素 s = list.firstChild, //滚动条滚动最小值 min = 0, //滚动条滚动最大值 max = list.offsetHeight - s.offsetHeight, _default = parseInt(sbody['data-height'] || sbody.getAttribute('data-height'), 10), unit = (sbody.scrollHeight - _default) / max, //firefox浏览器 firefox = 'MozBinding' in document.documentElement.style, //鼠标滚轮事件 mousewheel = firefox ? 'DOMMouseScroll' : 'mousewheel', //opera浏览器 opera = window.oprea && navigator.userAgent.indexOf('MSIE') === -1, //is firing mousedown event firing = false, //鼠标点击,定时器执行时间 interval, //滚动条距离容器高度 top, //滚动条当前top值 cur, //每次滚动多少像素 speed = 18; //变量缓存min, max this.limits[s] = { min: 0, max: max } //scroll事件 鼠标滑动滚轮移动滚动条 squid.on(elem, mousewheel, function(event) { var delta; if(event.wheelDelta) { delta = opera ? -event.wheelDelta / 120 : event.wheelDelta / 120 }else{ delta = -event.detail / 3 } cur = parseInt(s.style.top || 0, 10) //向上滚动 if(delta > 0) { top = cur - speed if(top < min) { top = min } }else{//向下滚动 top = cur + speed if(top > max) { top = max } } s.style.top = top + 'px' that.doScroll(sbody, top * unit) //阻止body元素滚动条滚动 event.preventDefault() }) //ie6, 7, 8下,如果鼠标连续点击两次且时间间隔太短,则第二次事件不会触发 //拖动滚动条,点击滚动条可到达区域 squid.on(list, 'mousedown', function(event) { var target = event.target, y = event.clientY; target = event.target if(target.tagName.toLowerCase() === 'shape') target = s //鼠标点击元素是滚动条 if(target === s) { //invoke elem setCapture s.setCapture && s.setCapture() that.scrolling.diffy = y - s.offsetTop //鼠标移动过程中判断是否正在拖动滚动条 that.scrolling.elem = s }else if(target.className.match('jscroll-list')){ firing = true interval = setInterval(function() { if(firing) { that.mouseHandle(list, y, unit) } }, 80) } }) //鼠标松开滚动条停止滚动 squid.on(list, 'mouseup', function() { //invoke elem releaseCapture s.releaseCapture && s.releaseCapture() firing = false clearInterval(interval) }) //滚动条元素获取焦点,可以触发keyup事件 squid.on(s, 'click', function() { this.focus() }) //滚动条获取焦点后,触发键盘上下键,滚动条滚动 squid.on(s, 'keydown', function(event) { var keyCode = event.keyCode, state = false; cur = parseInt(s.style.top || 0, 10) switch(keyCode) { case 38: top = cur - speed if(top < min) { top = min } state = true break case 40: top = cur + speed if(top > max) { top = max } state = true break default: break } if(state) { s.style.top = top + 'px' that.doScroll(sbody, top * unit) } event.preventDefault() }) }
(编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |