javascript jscroll模拟html成分滚动条

主流浏览器默感觉html成分提供的滚动条不佳看,何况前端开拓职员想对其经过css进行合併样式的说大话也是不行完毕的。比如ie能够因此体制来贯彻轻便的美化、Webkit内核浏览器能够决定滚动条的展现效果,firefox则不容许用户为滚动条定义样式。可是对于追求和睦的用户体验的前端开采人士,是不会被这么些浏览器的不同作为所阻止的。我们能够和睦通过规范的html成分模拟来落到实处自定义的滚动条。

此地是友善在办事不太忙的时候写出来了一个用户能够自定义的轮转条jscroll,以下简称jscroll。jscroll暗中认可只提供一种滚动条样式,部分样式来自google
webstore
,其中有部分css3样式主要用于落实圆角,阴影效果。为兑现跨浏览器景况下滚动条显示效果的同等,对于ie6,
7, 8不协理css3的浏览器引进了 PIE.htc
文件。上边就兑现的作用以及包容性、使用办法、具体代码完毕各自做一下教学。

完成效益以及包容性

jscroll完结了系统暗中同意滚动条的大约全部机能,比如:拖动滚动条查看内容、滚动鼠标滚轮查看内容、点击滚动条可到达区域的下边大概下方来触发滚动条的滚动、键盘上下键来触发滚动条的轮转。firefox、chrome,、ie9+
等新型浏览器辅助css3以及js的新式API,所以未有其余包容性难点。ie6, 7, 8
不帮忙css3由此引进PIE.htc
的hack文件来做合作管理。js方面临于不协助的API通过旧的API来做了十一分。有最大包容性难点的浏览器是ie6,不帮衬点击滚动条可达到区域来触发滚动条滚动,也不支持键盘上下键来触发滚动条的滚动。导致那几个主题材料的缘由根本是因为引进了支撑css3的PIE.htc文件,假诺不引进该hack文件,全数操作都能支撑,没有办法办为了显示效果的一律,只可以选择了不帮忙部分效应。

利用办法

使用自定义滚动条最多的气象相应是页面弹出层,或然是页面上某八个区域,千万不要对总体页面包车型地铁滚动条进行自定义操作。对于急需利用jscroll的成分,须要增加自定义属性data-scroll=”true”来报告程序须要运用jscroll来替换系统私下认可的滚动条,同期还索要通过加多自定义属性data-width=””、data-height=””来钦定成分要展现的宽度和中度。jscroll会根据用户定义的宽窄和惊人总括内容的来得升幅以及滚动条展现的惊人并累加交互的事件。

现实代码达成

jscroll的落到实处逻辑并不复杂,达成具体职能的js代码不到400行,不过此地信赖了一部分基础的不二等秘书技,所以必要引进squid.js作为基础艺术的支撑。对滚动条样式的支配的css在二个单独的jscroll-1.0.css文件之中,用户能够友善修改增添以满意本人的供给。上面是对落实具体职能的各样方法做三个轻便易行的分析:

复制代码 代码如下:

init: function(selector, context) {
selecotr = selector || ‘data-scroll’
context = context || document

var elems = squid.getElementsByAttribute(selector, context)
this.initView(elems)
}

init()是伊始化函数,依照内定selector和context获取须求使用自定义滚动条的要素,selector私下认可是data-scroll,上下文暗中同意是当前document。这里无论成分自定义属性data-scroll=”true”大概data-scroll=”false”都会动用自定滚动条覆盖体系私下认可滚动条,squid的getElementsByAttribute()方法只是提供经过元素是不是有钦命属性来搜索成分而忽略属性值,这么些主意未有jquery选择器只怕高端浏览器提供的querySelectorAll()方法庞大,因为这边squid只是做最基本的辅助。找到必要自定义滚动条的因素之后调用initView方法来初阶化滚动条全体布局和呈现。

复制代码 代码如下:

亚洲必赢app,initView: function(elems) {
var i = 0,
length = elems.length,
elem;

for(; i < length; i++) {
elem = elems[i]
if(this.hasScroll(elem)) {
this.create(elem)
}
}

this.initEvent()
}

initView()方法会首先对页面上得到的隐含自定义属性data-scroll的成分遍历,剖断每三个成分是还是不是会油不过生滚动条,通过hasScroll()方法判别。如若成分会现身滚动条则调用create()方法分别创造自定义的滚动条。initView()方法停止会调用initEvent()方法。

复制代码 代码如下:

//是或不是有滚动条
hasScroll: function(elem) {
return elem.offsetHeight < elem.scrollHeight
}

hasScroll()方法用于判别成分是还是不是会并发滚动条,重临true也许false。这里忽略成分的margin和padding,通过jscroll创造的滚动条暗中同意margin和padding都以0。

复制代码 代码如下:

//成立滚动条成分全体布局
create: function(elem) {
var wrapper,
list,
//滚动条成分
s,
//带滚动条成分展现的莫斯中国科学技术大学学
height = elem[‘data-height’] || elem.getAttribute(‘data-height’),
//带滚动条成分展现的增长幅度
width = elem[‘data-width’] || elem.getAttribute(‘data-width’),
//滚动条展现中度
value;

//wrapper
wrapper = document.createElement(‘div’)
wrapper.className = ‘jscroll-wrapper’
//forbid select text, for ie9
/*
* wrapper.onselectstart = function() {
* return false
* }
*/
squid.css(wrapper, {
height: height + ‘px’,
width: width + ‘px’
})

squid.addClass(elem, ‘jscroll-body’)
//overwrite the user define style
squid.css(elem, {
overflow: ‘visible’,
position: ‘absolute’,
height: ‘auto’,
width: (width – 40) + ‘px’,
padding: ‘0 20px 0 23px’
})

//list
list = document.createElement(‘div’)
list.className = ‘jscroll-list unselectable'<BR> list.unselectable
= ‘on’
squid.css(list, {
height: (height – 5) + ‘px’
})

//滚动条
s = document.createElement(‘div’)
s.className = ‘jscroll-drag unselectable’
s.unselectable = ‘on’
s.setAttribute(‘tabindex’, ‘1’)
s.setAttribute(‘hidefocus’, true)

list.appendChild(s)
wrapper.appendChild(list)
//把必要出现滚动条的要素包裹起来
elem.parentNode.replaceChild(wrapper, elem)
wrapper.insertBefore(elem, list)

//滚动条高度
value = this.scrollbarHeight(elem, height)
squid.css(s, {
height: value + ‘px’
})

//add event
this.regEvent(wrapper)
}

create()方法用户调度创设带有自定义滚动条的要素全体布局,首先通过创制了wrapper成分,用于包装会并发滚动条的成分elem和滚动条可滚动的区域成分list以及滚动条成分s。通过从出现滚动条成分设置的自定义属性data-width、data-height分别安装wrapper成分的幅度和惊人。通过scrollbarHeight()方法总计获得了滚动条成分突显的冲天,全部结构不算复杂。创造自定义滚动条全体布局从此是为滚动条成分s和滚动条可到达区域成分list增加事件管理,通过reg伊芙nt()方法完毕。

复制代码 代码如下:

//计算滚动条的莫斯中国科学技术大学学
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()
})
}

regEvent()方法完结了以下职能,应该是jscroll组件的主干措施了:

1.
鼠标在包含滚动条的成分区域,上下滚动鼠标滚轮,查看的内容跟随滚轮上下翻的成效

2.
点击滚动条可达到区域,即滚动条上方也许下方,滚动条和查阅的内容向上可能向下滚动。鼠标点击滚动条可达到区域不松手,可连续滚动滚动条和查阅的开始和结果,通过调用mouseHandle()方法来具体达成该意义。

  1. 点击滚动条成分后,能够由此键盘上下键来触发滚动条和查看内容的滚动

复制代码 代码如下:

//鼠标点击滚动条可达到区域方面或许下边时,滚动条滚动
mouseHandle: function(elem, place, unit) {
var prev = elem.previousSibling,
//包涵滚动条展现内容成分
a = prev.tagName.toLowerCase() === ‘div’ ? prev :
prev.previousSibling,
//
n = elem.firstChild,
//滚动条成分
s = this.ie6 ? n.lastChild : n.tagName.toLowerCase() === ‘div’ ? n :
n.nextSibling,
//滚动条中度
height,
//list元素距body的top值
value,
//滚动条距离容器中度
top,
//滚动条距body的top值
sTop,
//滚动条滚动最小值
min,
//滚动条滚动最大值
max,
//每点击滚动条可达到区域,滚动条向下或发展移动10px
step = 10,
//鼠标点击滚动条可达到区域距离最上部可能最底端小于distance时,滚动条能够自动移动到最最上端或然最低档
distance = 20;

min = this.limits[s].min
max = this.limits[s].max
height = s.offsetHeight
top = parseInt(s.style.top || 0, 10)
value = squid.getOffset(elem).top
sTop = squid.getOffset(s).top
//鼠标点击滚动条下方区域,滚动条向下滚动
if(place > sTop) {
if(value + elem.offsetHeight – place < distance && (elem.offsetHeight

  • height – top) < distance) {
    top = max
    }else{
    if((sTop + height + step) <= place) {
    top += step
    }else{
    top = place – value – height
    }
    }
    }else{
    //鼠标点击区域距滚动条顶部小于滚动条长度时,滚动条自动滚动到最上部
    if(place – value < distance && top < distance) {
    top = min
    }else{
    //滚动条距页面最上部高度减去鼠标clientY值大于step
    if(sTop – place >= step) {
    top -= step
    }else{
    top = place – value
    }
    }
    }
    if(top < min) {
    top = min
    }else if(top > max) {
    top = max
    }

s.style.top = top + ‘px’
this.doScroll(a, top * unit)
}

mouseHandle()方法通过剖断鼠标点击地方在页面中的地点坐标,和滚动条成分在页面中的地方来决断是点击了滚动条的下边区域依旧下方区域。假若点击了凡间区域则滚动条向下滚动,不然向上滚动,对于点击的地方在上边区域依然下方区域小于distance值时,滚动条自动滚动到最小值恐怕最大值。

来得效果

该控件的demo使用了Taobao网用户注册协议内容,因为firefox、chrome等高等浏览器都能保障很好的包容性和显示效果,所以这里只呈现ie低版本浏览器显示效果,
ie浏览器展现截图如下:

ie6下

亚洲必赢app 1

初始化之后

亚洲必赢app 2

滚动进程中

亚洲必赢app 3

滚动到底层

ie7

亚洲必赢app 4

滚动条开首化之后

亚洲必赢app 5

滚动进程中

亚洲必赢app 6

滚动到最头部

ie9

亚洲必赢app 7

千帆竞发滚动前

亚洲必赢app 8

滚动进程中

亚洲必赢app 9

滚动到最终面部分

总结:基本的效果与利益达成代码就这么多了,只怕深入分析的相当不足细致,里面涉及最多的恐怕就是岗位的计量,事件的绑定管理。若是有何样难题,接待一起沟通、学习、沟通。

注意:PIE.htc文件路线要摆正确,援用时写成绝对路线,不然在ie6, 7,
8下并未有css3的功力(倘若那样自个儿代码里所做的相称管理就没啥意思了!),须求改造援用路线的话能够在jscroll-1.0.css文件中期维修改。最终附上源码,应接感兴趣者下载试用。

你大概感兴趣的小说:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图