js代码写法求助 关于操作vuejs 设置滚动条位置

原生js实现模拟滚动条
转载 &更新时间:日 11:07:05 & 投稿:hebedich
本文给大家分享的是使用原生javascript实现模拟滚动条的方法及代码,效果非常棒,有需要的小伙伴可以参考下。
当页面中有很多滚动条,它们相互嵌套,很不好看,这时就会模拟滚动条,并给这个滚动条好看的样式,使得页面美观。
模拟滚动条很多时候是去用jquery插件,然后写几行代码就搞定了。不过随着mvvm的快速发展,很多时候都懒得用jquery了,这就是本文的动机,本屌力求用简单的不依赖jquery只依赖mvvm(avalon) api的代码,完成一个简易的滚动条。
1.鼠标滚轮可以让滚动条工作,界面滚动
2.鼠标可以拖动滚动条并让界面滚动
3.页面resize时,滚动条根据页面尺寸变化,仍然可以工作
很显然,这个组件是基于拖动drag的,本屌又不想重新写,就只有改下ui框架的drag了,这里改的是easy js ui的drag组件。用easy js是因为注释比较多,代码简洁。
本屌把easy js ui的drag组件里的相应方法换成avalon api里的方法,删掉prototype里的方法及冗余代码
define('drag',['avalon-min'],function(avalon){
function getBoundary(container, target) {
var borderTopWidth = 0, borderRightWidth = 0, borderBottomWidth = 0, borderLeftWidth = 0, cOffset = avalon(container)
.offset(), cOffsetTop = cOffset.top, cOffsetLeft = cOffset.left, tOffset = avalon(target)
.offset();
borderTopWidth = parseFloat(avalon.css(container,'borderTopWidth'));
borderRightWidth = parseFloat(avalon.css(container,'borderRightWidth'));
borderBottomWidth = parseFloat(avalon.css(container,'borderBottomWidth'));
borderLeftWidth = parseFloat(avalon.css(container,'borderLeftWidth'));
cOffsetTop = cOffsetTop - tOffset.top + parseFloat(avalon(target).css('top'));
cOffsetLeft = cOffsetLeft - tOffset.left + parseFloat(avalon(target).css('left'));
top : cOffsetTop + borderTopWidth,
right : cOffsetLeft + avalon(container).outerWidth() - avalon(target).outerWidth()
- borderRightWidth,
left : cOffsetLeft + borderLeftWidth,
bottom : cOffsetTop + avalon(container).outerHeight() - avalon(target).outerHeight()
- borderBottomWidth
var drag = function(target, options) {
var defaults = {
axis:null,
container:null,
handle:null,
ondragmove:null
var o =avalon.mix(defaults,options),
doc = target.ownerDocument,
win = doc.defaultView || doc.parentWindow,
originHandle=target,
isIE =!-[1,],
handle = isIE ? target :doc,
container = o.container ?o.container: null,
count = 0,
drag = this,
axis = o.axis,
isMove = false,
boundary, zIndex, originalX, originalY,
clearSelect = 'getSelection' in win ? function(){
win.getSelection().removeAllRanges();
} : function(){
doc.selection.empty();
catch( e ){};
down = function( e ){
o.isDown =
var newTarget = target,
left, top,
o.width = avalon(target).outerWidth();
o.height = avalon(target).outerHeight();
o.handle =
left = avalon(newTarget).css( 'left' );
top = avalon(newTarget).css( 'top' );
offset = avalon(newTarget).offset();
drag.left = left = parseInt( left );
drag.top = top = parseInt( top );
drag.offsetLeft = offset.
drag.offsetTop = offset.
originalX = e.pageX -
originalY = e.pageY -
if( (!boundary && container)){
boundary = getBoundary(container, newTarget );
if( axis ){
if( axis === 'x' ){
originalY =
else if( axis === 'y' ){
originalX =
if( isIE ){
handle.setCapture();
avalon.bind(handle,'mousemove',move);
avalon.bind(handle,'mouseup',up);
if( isIE ){
avalon.bind(handle,'losecapture',up);
e.stopPropagation();
e.preventDefault();
move = function( e ){
if( !o.isDown ){
if( count % 2 === 0 ){
var currentX = e.pageX,
currentY = e.pageY,
style = target.style,
x, y, left, right, top,
clearSelect();
if( originalX ){
x = currentX - originalX;
if( boundary ){
left = boundary.
right = boundary.
x = x & left ? left :
x & right ? right :
drag.left =
drag.offsetLeft = currentX - e.offsetX;
style.left = x + 'px';
if( originalY ){
y = currentY - originalY;
if( boundary ){
top = boundary.
bottom = boundary.
y = y & top ? top :
y & bottom ? bottom :
drag.top =
drag.offsetTop = currentY - e.offsetY;
style.top = y + 'px';
o.ondragmove.call(this,drag);
e.stopPropagation();
up = function( e ){
o.isDown =
if( isIE ){
avalon.unbind(handle,'losecapture' );
avalon.unbind( handle,'mousemove');
avalon.unbind( handle,'mouseup');
if( isIE ){
handle.releaseCapture();
e.stopPropagation();
avalon(originHandle).css( 'cursor', 'pointer' );
avalon.bind( originHandle,'mousedown', down );
drag.refresh=function(){
boundary=getBoundary(container,target);
另外在最后暴露的drag上加了一个refresh()方法,作用是在resize时,需要更新滚动条可以拖动的范围。这个方法在scrollbar的更新视图中会用到。
drag.refresh=function(){
boundary=getBoundary(container,target);
还有在滚动条拖动过程move中,添加一个钩子,允许从外面添加一个监听函数,拖动时会触发监听函数,并传入drag参数。
o.ondragmove.call(this,drag);
然后是scrollbar.js
define('scrollbar',['avalon-min','drag'],function(avalon,drag){
function scrollbar(wrap,scrollbar,height_per_scroll){//容器,滚动条,每次滚轮移动的距离
this.scroll_height=0;//滚动条高度
this.dragger=//drag组件实例
wrap.scrollTop=0;
//容器的位置要减去浏览器最外面的默认滚动条垂直方向位置
var self=this,wrap_top=avalon(wrap).offset().top-avalon(document).scrollTop();
function ondragmove(drag){//drag组件拖动时的监听函数,更新容器视图
wrap.scrollTop=(parseFloat(scrollbar.style.top)-wrap_top)*
(wrap.scrollHeight -wrap.clientHeight)/(wrap.clientHeight-self.scroll_height);
function setScrollPosition(o) {//更新滚动条位置
scrollbar.style.top =o.scrollTop*wrap.clientHeight/wrap.scrollHeight+wrap_top+ 'px';
function inti_events(){
avalon.bind(wrap,'mousewheel',function(e){
if(e.wheelDelta & 0)
wrap.scrollTop+=height_per_
wrap.scrollTop-=height_per_
setScrollPosition(wrap);
e.preventDefault();
self.dragger=new drag(scrollbar,{container:wrap,axis:'y',ondragmove:ondragmove});
window.onresize=function(){
self.refresh_views();
self.dragger.refresh();
this.refresh_views=function(){//更新组件所有部分视图,并暴露供外部调用
//容器高度这里设置成浏览器可视部分-容器垂直方向位置,没有考虑容器有border,padding,margin.可根据相应场景修改
wrap.style.height=document.documentElement.clientHeight-wrap_top+'px';
self.scroll_height=wrap.clientHeight*wrap.clientHeight/wrap.scrollH
//容器高度等于滚动条高度,隐藏滚动条
if(self.scroll_height==wrap.clientHeight)
scrollbar.style.display='none';
scrollbar.style.display='block';
scrollbar.style.height=self.scroll_height+'px';
setScrollPosition(wrap);
function init(){
self.refresh_views();
inti_events();
可以看到,在resize时,调用了drag组件的refresh方法,更新滚动条可以拖动的范围。这里暴露了refresh_views()方法,以应对外部需要手动更新视图的情况。比如,聊天分组的折叠和展开。
这样就完成了简易滚动条。代码很简单,如果出问题需要fix bug或定制的话,也很容易。
以上所述上就是本文的全部内容了,希望大家能够喜欢。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具原生js实现滚动条 - Cosimo - 博客园
var SimulateScroll = (function(){
var oParent = document.getElementById('wrap-scroll-bar'),
oBox = document.getElementById('scroll-bar'),
oWp = document.getElementById('container'),
oDiv = document.getElementById('cont'),
bDown = true,
downFun = function(ev){
var oEv = ev ||
var disY = oEv.clientY - oBox.offsetT
document.onmousemove = function(ev){
var oEv = ev ||
var l = oEv.clientY - disY;
setTop(l);
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
return false;
function mouseWheel(ev){
var oEv = ev ||
bDown = oEv.wheelDelta ? oEv.wheelDelta & 0 : oEv.detail & 0;
if(bDown){
setTop(oBox.offsetTop + 10);
setTop(oBox.offsetTop - 10);
if(oEv.preventDefault){
oEv.preventDefault();
return false;
function setTop(l){
var h = oParent.offsetHeight - oBox.offsetH
if(l & 0){
}else if(l & h){
oBox.style.top = l + 'px';
var bl = l/h;
oDiv.style.top =- (oDiv.offsetHeight - oWp.offsetHeight) * bl + 'px';
function setBarHeight(){
var containerHeight = oWp.offsetHeight,
contentHeight = oDiv.offsetH
oBox.style.height = (containerHeight * containerHeight /contentHeight) + 'px';
function addEvent(obj, sEv, fn){
if(obj.addEventListener){
obj.addEventListener(sEv,fn,false);
obj.attachEvent('on' + sEv,fn);
oWp : oWp,
oDiv : oDiv,
scrollHidden : function(){
oBox.style.height = 0;
oBox.style.top = 0;
oDiv.style.top = 0;
oBox.onmousedown = null;
query.EventUtil.remove(oParent, 'mousewheel', mouseWheel);
query.EventUtil.remove(oParent, 'DOMMouseScroll', mouseWheel);
query.EventUtil.remove(oWp, 'mousewheel', mouseWheel);
query.EventUtil.remove(oWp, 'DOMMouseScroll', mouseWheel);
isScrollShow : function(){
if(oDiv.offsetHeight & oWp.offsetHeight){
SimulateScroll.inIt();
SimulateScroll.scrollHidden();
inIt : function(){
setBarHeight();
oBox.onmousedown = downF
query.EventUtil.add(oParent, 'mousewheel', mouseWheel);
query.EventUtil.add(oParent, 'DOMMouseScroll', mouseWheel);
query.EventUtil.add(oWp, 'mousewheel', mouseWheel);
query.EventUtil.add(oWp, 'DOMMouseScroll', mouseWheel);
SimulateScroll.isScrollShow();
query.EventUtil.add(window,'resize',SimulateScroll.isScrollShow);
//query.EventUtil 为原生js事件库。如需使用以上滚动条方法,需加上事件库,或者改为jq写法
&html结构:
随笔 - 174纯Js实现的滚动条效果_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
纯Js实现的滚动条效果
&&纯Js实现的滚动条效果
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢博客分类:
首先需要一个容器,滑动范围就在这个容器里面,还有是容器里面的绝对定位的滑块,基本就是这两部分。
滑块拖放的部分请参考拖放效果,这里我把拖放程序扩展了一个设置滑块位置的SetPos方法方便程序使用。
【水平和垂直滑动】
程序支持水平和垂直滑动,设置Horizontal属性为true就是水平滑动(默认),为false就是垂直滑动。
这个属性只能在实例化时设置,初始化之后会就不要修改了。
程序初始化时就根据这个属性锁定拖放的方向:
this._drag[this._horizontal ? "LockY" : "LockX"] =
程序支持两个方向的滑动,如果每次都判断一下再分别设置参数会很麻烦,
所以程序中每次滑动都计算两个方向的位置参数,并把参数直接交给_drag来处理。
由于_drag在实例化时已经做了范围限制和方向锁定,已经带了位置参数修正,所以可以直接交给它处理。
这样虽然效率差点,但就能大大降低复杂度,我想还是值得的。
【自动滑移】
运行Run自动滑移程序后,就会自动滑移,参数可以设置滑移的方向(true为右/下,false为左/上)。
步长是根据百分比来设置的
var percent = this.GetPercent() + (bIncrease ? 1 : -1) * this.RunStep / 100;
this.SetPos((this.Container.clientWidth - this.Bar.offsetWidth) * percent, (this.Container.clientHeight - this.Bar.offsetHeight) * percent);
然后通过位置属性判断是否到了极限值,不是的话就用一个定时器继续滑动:
if(!(bIncrease ? this._IsMax : this._IsMin)){
this._timer = setTimeout(Bind(this, this.Run, bIncrease), this.RunTime);
【缓动滑移】
除了SetPos还有一个EasePos缓动滑移程序可以设置滑块位置。
如果Ease属性是false时,EasePos跟SetPos一样直接设置位置,为true时就会缓动(减速)设置位置。
其中缓动的效果请参考图片切换展示效果 ,程序中如果目标值超过极限值时不能直接判断是否到达目标值,不过可以用_IsMid属性(参考位置判断部分)来判断没有到极限值。
注意,因为要跟offset取的值比较,而offset取的值是整数,所以参数必须转换成整数(程序用Math.round处理了),否则如果是小数那就永远都不会相等(死循环)了。
ps:程序只在鼠标点击控制和设置百分比位置中使用了EasePos,其它情况比较适合用SetPos。
【百分比和值】
这个是基本功能了,先看看GetPercent获取百分比程序,这个百分比就是滑块左边距离跟滑动区域的比例:
return this._horizontal ? this.Bar.offsetLeft / (this.Container.clientWidth - this.Bar.offsetWidth)
: this.Bar.offsetTop / (this.Container.clientHeight - this.Bar.offsetHeight)
注意滑动区域是容器的clientWidth减去滑块的offsetWidth(关于这两个属性详细请看这里)。
对应的有SetPercent设置百分比位置程序,就是根据百分比参数设置滑块的位置:
this.EasePos((this.Container.clientWidth - this.Bar.offsetWidth) * value, (this.Container.clientHeight - this.Bar.offsetHeight) * value);
滑动条更多的应用是在于值的运用。程序中属性MinValue和MaxValue分别设置最小值和最大值。
ps:虽然说是最大值,但不一定就比较大的,不过这样写起来比较方便。
当设置了这两个属性(值)就能GetValue获取当前值了:
return this.MinValue + this.GetPercent() * (this.MaxValue - this.MinValue);
对应的SetValue设置值位置程序:
this.SetPercent((value- this.MinValue)/(this.MaxValue - this.MinValue));
这个很简单,懂点数学应该都明白了。
【位置状态】
程序中有位置程序onMin(最小值时)、onMax(最大值时)和onMid(中间值时)分别在各自位置时执行。
ps:onMid指的是除最小值最大值外的中间部分,不是中心值。
程序是在Move滑动程序中通过百分比来判断当前位置的(0时为最小值,1时为最大值,其他为中间值)。
由于Move程序并不会因为到了极限值就停止,如果仅仅根据百分比来判断那么到了极限值,值虽然不变但程序就会一直被触发。
而我需要的是当值不变的时候,对应位置程序仅仅触发一次。根据需求就衍生出三个位置状态属性_IsMin(最小值状态)、_IsMax(最大值状态)和_IsMid(中间值状态)。
用这几个状态属性和百分比就能实现需要的效果了:
var percent = this.GetPercent();
//最小值判断
if(percent & 0){
this._IsMin =
if(!this._IsMin){ this.onMin(); this._IsMin = }
//最大值判断
if(percent & 1){
this._IsMax =
if(!this._IsMax){ this.onMax(); this._IsMax = }
//中间值判断
if(percent & 0 && percent & 1){
if(!this._IsMid){ this.onMid(); this._IsMid = }
this._IsMid =
}这三个位置状态属性在其他程序中也用来判断是否到了极限值。
【鼠标拖动控制】
鼠标拖动控制,就是通过拖动滑块来设置定位。
这个就跟滚动条意思差不多,主要是通过_drag本身的拖放效果来实现的(详细看这里拖放效果)。
【鼠标点击控制】
鼠标点击控制,就是当点击容器的时候能定位到点击的位置。
一般来说只要把ClickCtrl鼠标点击控制程序绑定容器的click事件中就可以了。
但这里有个问题,滑块的点击(拖动控制)跟容器的点击会发生冲突,具体表现是拖放结束后就“顺便”触发了容器的click。
这个本来在滑块的点击事件中取消冒泡就可以:
addEventHandler(this.Bar, "click", BindAsEventListener(this, function(e){ e.stopPropagation(); }));
&div style="width:100 height:100 background-color:#CCC;" onclick="alert(1)" &
&div style=" height:50 background-color:#C11;" onclick="event.stopPropagation?event.stopPropagation():(event.cancelBubble=true);" &&/div&
里面的div取消冒泡,点击它不会触发外面div的onclick,但如果在里面的div点,然拖动到外面的div放,就会触发了,而ff是不会的。
ps:从外面拖到里面也是一样的情况。
经过测试,我觉得是因为ie认为点击的点和放只要是发生在同一个元素的内部(包括内部的其他元素),那个这个点击就是有效的;而ff则认为点击的点和放必须在同一个元素内才有效(w3c标准应该也是这样)。
这个导致的问题是,当拖放结束时如果放开鼠标的地方是容器上,那么就会发生冲突了。
那对于ie的这个现象,解决方法其实也很多,我用的方法很简单,设一个属性_ondrag来表示是否拖放中。
具体就是在DragStart开始拖放滑动程序中把_ondrag设为true,并在DragStop结束拖放滑动程序中把它设为false:
setTimeout(Bind(this, function(){ this._ondrag = }), 10);
这里用了setTimeout,因为拖放结束后才会触发容器的click,所以设一个延时,使这个值在容器的click触发后才修改。
这样就可以通过这个_ondrag来判断是否应该执行ClickCtrl了:
addEventHandler(this.Container, "click", BindAsEventListener(this, function(e){ this._ondrag || this.ClickCtrl(e);}));
接着看ClickCtrl鼠标点击控制程序,首先获取容器的相对文档的位置:
var o = this.Container, iLeft = o.offsetLeft, iTop = o.offsetT
while (o.offsetParent) { o = o.offsetP iLeft += o.offsetL iTop += o.offsetT }
注意,要逐级向上获取才能取得相对相对文档的位置。
然后通过pageX(pageY)和滑块(这里是要设置到滑块的中间位置所以取一半)得到要设置的位置:
this.EasePos(e.pageX - iLeft - this.Bar.offsetWidth / 2, e.pageY - iTop - this.Bar.offsetHeight / 2);
这里要用pageX(pageY)来取值,而不是clientX(clientY),因为后者是没有计算滚动条的。
ps:ie没有pageX(pageY),不过在Event程序中已经给window.event添加了这个属性:
oEvent.pageX = oEvent.clientX + document.documentElement.scrollL
oEvent.pageY = oEvent.clientY + document.documentElement.scrollT
【鼠标滚轮控制】
鼠标滚轮控制,就是通过鼠标滚轮滚动来控制滑块的滑动。
首先ie绑定滚轮事件用的是mousewheel,ff用的是DOMMouseScroll,所以在WheelBind绑定鼠标滚轮程序中是这样设置的:
addEventHandler(o, isIE ? "mousewheel" : "DOMMouseScroll", BindAsEventListener(this, this.WheelCtrl));
接着看WheelCtrl鼠标滚轮控制程序,通过event的detail属性可以获取鼠标滚动的距离(值大小)和方向(正负)。
利用它来设置要滑动的位置:
var i = this.WheelSpeed * e.
this.SetPos(this.Bar.offsetLeft + i, this.Bar.offsetTop + i);
但ie没有detail,对应的有wheelDelta,wheelDelta的数值刚好是detail的40倍,而且方向相反(正负相反),所以Event程序中是这样给window.event添加detail的:
oEvent.detail = oEvent.wheelDelta / (-40);
为了防止触发其他滚动条,这里用了preventDefault取消默认动作。
注意不是用取消冒泡(貌似滚屏是事件的默认动作)。
【方向键控制】
方向键控制,就是通过键盘的左右(上下)方向键来控制滑块的滑动。
首先用KeyBind方向键绑定程序把KeyCtrl方向键控制程序绑定到对象的keydown事件中:
addEventHandler(o, "keydown", BindAsEventListener(this, this.KeyCtrl));
在KeyCtrl中,通过event的keyCode属性获取键盘的按键(左37、上38、右39、下40)并进行相应的操作:
switch (e.keyCode) {
case 37 ://左
iLeft -= iW
case 38 ://上
iTop -= iH
case 39 ://右
iLeft += iW
case 40 ://下
iTop += iH
//不是方向按键返回
同样为了防止触发其他滚动条,也用了preventDefault取消默认动作。
【focus和tabIndex】
在KeyBind程序中,除了绑定对象的keydown事件,还不够的,可以在ff测试下面的代码:
&div style="width:100 height:100 background-color:#CCC;" onkeydown="alert(1)"&&/div&
无论怎样都触发不了onkeydown事件(ie可以触发),那就奇怪了,按照一般的思路应该是可以的啊。
这个可以从w3c关于KeyboardEvent的部分中找到原因:
Keyboard events are commonly directed at the element that has the focus.
大概就是说键盘按键事件一般指向能获取焦点的元素,就是不能获取焦点的元素就不能触发键盘按键事件了。
难道div就不能获取焦点?用下面的代码测试(ff):
&div id="test" style="width:100 height:100 background-color:#CCC;" onfocus="alert(1)"&&/div&
&script&document.getElementById("test").focus();&/script&
还真的不行,那问题就在于怎么使div能获取焦点了(当然这个是转了不少弯才想出来的)。
最后发现给元素设置tabIndex就能让元素能获取焦点了,如果不需要详细了解的话下面可以略过。
首先看看w3c关于onfocus的部分:
The onfocus event occurs when an element receives focus either by the pointing device or by tabbing navigation.
This attribute may be used with the following elements: A, AREA, LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.
当元素通过指定(点击)或tab导航(Tabbing navigation)获得焦点,onfocus事件就会触发。
该属性会使用在以下元素(就是说默认可以获取焦点的元素):A, AREA, LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.
测试下面的代码:
&a href="#" onfocus="alert(1)" onkeydown="alert(2)"&focus&/a&
果然两个事件都可以执行。
接着看Tabbing navigation的部分:
Those elements that do not support the tabindex attribute or support it and assign it a value of "0" are navigated next. These elements are navigated in the order they appear in the character stream.
这里看得不太明白,关键的意思是给元素设置tabindex为0就可以被导航到了(能获取焦点了)。
测试下面的代码(ff):
&div tabindex="0" style="width:100 height:100 background-color:#CCC;" onfocus="alert(1)" onkeydown="alert(2)"&&/div&
果然两个事件都能触发了。
不过w3c说得很模糊,msdn上倒是很清楚:
An element can have focus if the tabIndex property is set to any valid negative or positive integer.
Elements that receive focus can fire the onblur and onfocus events as of Internet Explorer 4.0, and the onkeydown, onkeypress, and onkeyup events as of Internet Explorer 5.
只要元素的tabIndex属性设置成任何有效的整数那么该元素就能取得焦点。元素在取得焦点后就能触发onblur,onfocus,onkeydown, onkeypress和onkeyup事件。
不同tabIndex值在tab order(Tabbing navigation)中的情况:
Objects with a positive tabIndex are selected in increasing iIndex order and in source order to resolve duplicates.
Objects with an tabIndex of zero are selected in source order.
Objects with a negative tabIndex are omitted from the tabbing order.
tabIndex值是正数的对象根据递增的值顺序和代码中的位置顺序来被选择
tabIndex值是0的对象根据在代码中的位置顺序被选择
tabIndex值是负数的对象会被忽略
这个不知道是否符合标准,但貌似ff跟ie是一样的(不同的地方后面会说)。
那么设置一个负的tabIndex值应该是最理想的了。
ps:如果对ff的tabindex有兴趣的话,推荐看看Test cases for tabindex bugs in Firefox,里面有更详细更专业的分析。
那ie通过一开始的测试,是不是就说明不需要了呢?我们换一个元素测试:
&ul style="width:100 height:100 background-color:#CCC;" onfocus="alert(1)" onkeydown="alert(2)"&&/ul&
换成ul就又不能触发事件了,怎么搞的。
再看看msdn,里面有一段:
The following elements can have focus by default but are not tab stops. .略. applet, div, frameSet, span, table, td.
下面的元素默认能获取焦点但不能tab导航:applet, div, frameSet, span, table, td.
看来ie真是“为程序员着想”,但其他元素总不能漏了啊,还是全部都设置tabIndex好了。
终于回到程序上来,首先设置tabIndex:
o.tabIndex = -1;
ff元素获得焦点后会出现一个虚线框,去掉会美观一点:
isIE || (o.style.outline = "none");
ps:如果tabIndex设为0或以上的话ie也会出现虚线框。
绑定了keydown之后,点击一下容器(获取焦点)后就能用方向键控制方向了,但如果(没有获得焦点时)点击滑块,还是触发不了事件。
因为滑块在拖动效果中ie的鼠标捕获和ff的取消默认动作导致容器不能获得焦点,那手动设置可以吗?
是可以的,ff中就是直接在滑块的mousedown事件中执行容器的focus方法获得焦点。
ie本来也是可以的,但ie中当对象执行focus方法时,如果该对象有部分在滚动条外就会自动滚动到适当的位置(还好点击不会这样)。
为了降低影响,程序中把滑块也绑定了键盘控制,这样点击滑块时只要执行滑块的focus方法获得焦点就可以了:
var oFocus = isIE ? (this.KeyBind(this.Bar), this.Bar) : this.C
addEventHandler(this.Bar, "mousedown", function(){ oFocus.focus(); });
ps:由于focus并不会冒泡(w3c标准),所以不用担心滑块的focus导致容器获得焦点。
ps2:w3c的文档还真是难读,还是msdn的易懂。
【样式设置】
程序没有对margin之类的样式进行处理,所以尽量使用“干净”的元素,如果用ul那些,请先“清理”好。
在仿Apple滑动条产品展示效果中,像那样横排的展示,最好是放在table里才能保证不换行,否则就要放一个很长很长的副容器来放内容。
里面还有一个样式比较特别的,细心的话可以看到滑块是突出了一个半圆,而且是刚好能嵌在两端的。
这里主要是滑块两边的两个层(两个半圆)使用了绝对定位,设置了负的位置值(左边是负的left,右边是负的right)。
还有就是到达两端时对应的层会自动换一个背景图,但其实是同一张图:
这里是用了变换背景图位置的方法,这个方法也不新鲜了,这里要说说的是,虽然只是换垂直方向的坐标,但backgroundPositionY只是ie的方法,所以还是要用backgroundPosition。
【应用技巧】
在仿Apple滑动条产品展示效果中,可以看到MaxValue设成了内容容器的scrollWidth和clientWidth之差:
MaxValue: $("idContent").scrollWidth - $("idContent").clientWidth,
其实这个值就是内容容器scrollLeft的最大值,这样在滑动时要设置的内容容器的scrollLeft刚好就是GetValue方法的值了(预览效果2也一样):
onMove: function(){ $("idContent").scrollLeft = this.GetValue(); }
预览效果2中,滑块的高度也特别设置过:
$("idBar2").style.height = $("idSlider2").clientHeight * Math.min($("idContent2").clientHeight / $("idContent2").scrollHeight, 1) - 4 + "px";
其实就是使内容跟内容容器的高度之比等于滑块跟滑动容器之比,当然这个比不能大于1,否则就滑块高度就超过容器高度了,里面的4是边框宽度。
这样的好处是滑块会根据实际内容自动设置大小,就像一般的滚动条,内容越多滚动条就越小,反之就越大,这利于用户体验。
ps:仿Apple那个为了突出效果所以没有设置,实际应用中也应该这样设置一下。
预览效果3中,从GetValue和GetPercent取得的数有可能是很长的小数,所以显示时必须处理一下。
这里看到程序中parseInt使用了两个参数,而且第二个参数是10,是不是多余的呢?
不是的,因为手册上说了:
如果没有提供,则前缀为 '0x' 的字符串被当作十六进制,前缀为 '0' 的字符串被当作八进制。所有其它字符串都被当作是十进制的。
而对于手动输入的数字,前面加了个0也是很普通的情况,这样无意间就会变成八进制了。
首先实例化一个滑动条对象,需要两个参数,分别是滑动容器和滑块(滑块要在容器里面哦):
var sld = new Slider("idSlider", "idBar")
有以下这些可选参数和属性:
属性:默认值//说明
MinValue: 0,//最小值
MaxValue: 100,//最大值
WheelSpeed: 5,//鼠标滚轮速度,越大越快(0则取消鼠标滚轮控制)
KeySpeed:& 50,//方向键滚动速度,越大越慢(0则取消方向键控制)
Horizontal: true,//是否水平滑动
RunTime: 20,//自动滑移的延时时间,越大越慢
RunStep: 2,//自动滑移每次滑动的百分比
Ease:& false,//是否缓动
EaseStep: 5,//缓动等级,越大越慢
onMin:& function(){},//最小值时执行
onMax:& function(){},//最大值时执行
onMid:& function(){},//中间值时执行
onDragStart:function(){},//拖动开始时执行
onDragStop: function(){},//拖动结束时执行
onMove:& function(){}//滑动时执行
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&meta http-equiv="Content-Type" content="text/ charset=gb2312" /&
&title&JavaScript 滑动条效果&/title&
var isIE = (document.all) ? true :
var $ = function (id) {
return "string" == typeof id ? document.getElementById(id) :
var Class = {
create: function() {
return function() { this.initialize.apply(this, arguments); }
var Extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
var Bind = function(object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function() {
return fun.apply(object, args);
var BindAsEventListener = function(object, fun) {
return function(event) {
return fun.call(object, Event(event));
function Event(e){
var oEvent = isIE ? window.event :
if (isIE) {
oEvent.pageX = oEvent.clientX + document.documentElement.scrollL
oEvent.pageY = oEvent.clientY + document.documentElement.scrollT
oEvent.preventDefault = function () { this.returnValue = };
oEvent.detail = oEvent.wheelDelta / (-40);
oEvent.stopPropagation = function(){ this.cancelBubble = };
var CurrentStyle = function(element){
return element.currentStyle || document.defaultView.getComputedStyle(element, null);
function addEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.addEventListener) {
oTarget.addEventListener(sEventType, fnHandler, false);
} else if (oTarget.attachEvent) {
oTarget.attachEvent("on" + sEventType, fnHandler);
oTarget["on" + sEventType] = fnH
function removeEventHandler(oTarget, sEventType, fnHandler) {
if (oTarget.removeEventListener) {
oTarget.removeEventListener(sEventType, fnHandler, false);
} else if (oTarget.detachEvent) {
oTarget.detachEvent("on" + sEventType, fnHandler);
oTarget["on" + sEventType] =
//滑动条程序
var Slider = Class.create();
Slider.prototype = {
//容器对象,滑块
initialize: function(container, bar, options) {
this.Bar = $(bar);
this.Container = $(container);
this._timer =//自动滑移的定时器
this._ondrag =//解决ie的click问题
//是否最小值、最大值、中间值
this._IsMin = this._IsMax = this._IsMid =
//实例化一个拖放对象,并限定范围
this._drag = new Drag(this.Bar, { Limit: true, mxContainer: this.Container,
onStart: Bind(this, this.DragStart), onStop: Bind(this, this.DragStop), onMove: Bind(this, this.Move)
this.SetOptions(options);
this.WheelSpeed = Math.max(0, this.options.WheelSpeed);
this.KeySpeed = Math.max(0, this.options.KeySpeed);
this.MinValue = this.options.MinV
this.MaxValue = this.options.MaxV
this.RunTime = Math.max(1, this.options.RunTime);
this.RunStep = Math.max(1, this.options.RunStep);
this.Ease = !!this.options.E
this.EaseStep = Math.max(1, this.options.EaseStep);
this.onMin = this.options.onM
this.onMax = this.options.onM
this.onMid = this.options.onM
this.onDragStart = this.options.onDragS
this.onDragStop = this.options.onDragS
this.onMove = this.options.onM
this._horizontal = !!this.options.H//一般不允许修改
//锁定拖放方向
this._drag[this._horizontal ? "LockY" : "LockX"] =
//点击控制
addEventHandler(this.Container, "click", BindAsEventListener(this, function(e){ this._ondrag || this.ClickCtrl(e);}));
//取消冒泡,防止跟Container的click冲突
addEventHandler(this.Bar, "click", BindAsEventListener(this, function(e){ e.stopPropagation(); }));
//设置鼠标滚轮控制
this.WheelBind(this.Container);
//设置方向键控制
this.KeyBind(this.Container);
//修正获取焦点
var oFocus = isIE ? (this.KeyBind(this.Bar), this.Bar) : this.C
addEventHandler(this.Bar, "mousedown", function(){ oFocus.focus(); });
//ie鼠标捕获和ff的取消默认动作都不能获得焦点,所以要手动获取
//如果ie把focus设置到Container,那么在出现滚动条时ie的focus可能会导致自动滚屏
//设置默认属性
SetOptions: function(options) {
this.options = {//默认值
MinValue: 0,//最小值
MaxValue: 100,//最大值
WheelSpeed: 5,//鼠标滚轮速度,越大越快(0则取消鼠标滚轮控制)
50,//方向键滚动速度,越大越慢(0则取消方向键控制)
Horizontal: true,//是否水平滑动
RunTime: 20,//自动滑移的延时时间,越大越慢
RunStep: 2,//自动滑移每次滑动的百分比
false,//是否缓动
EaseStep: 5,//缓动等级,越大越慢
function(){},//最小值时执行
function(){},//最大值时执行
function(){},//中间值时执行
onDragStart:function(){},//拖动开始时执行
onDragStop: function(){},//拖动结束时执行
function(){}//滑动时执行
Extend(this.options, options || {});
//开始拖放滑动
DragStart: function() {
this.onDragStart();
this._ondrag =
//结束拖放滑动
DragStop: function() {
this.onDragStop();
setTimeout(Bind(this, function(){ this._ondrag = }), 10);
Move: function() {
this.onMove();
var percent = this.GetPercent();
//最小值判断
if(percent & 0){
this._IsMin =
if(!this._IsMin){ this.onMin(); this._IsMin = }
//最大值判断
if(percent & 1){
this._IsMax =
if(!this._IsMax){ this.onMax(); this._IsMax = }
//中间值判断
if(percent & 0 && percent & 1){
if(!this._IsMid){ this.onMid(); this._IsMid = }
this._IsMid =
//鼠标点击控制
ClickCtrl: function(e) {
var o = this.Container, iLeft = o.offsetLeft, iTop = o.offsetT
while (o.offsetParent) { o = o.offsetP iLeft += o.offsetL iTop += o.offsetT }
//考虑有滚动条,要用pageX和pageY
this.EasePos(e.pageX - iLeft - this.Bar.offsetWidth / 2, e.pageY - iTop - this.Bar.offsetHeight / 2);
//鼠标滚轮控制
WheelCtrl: function(e) {
var i = this.WheelSpeed * e.
this.SetPos(this.Bar.offsetLeft + i, this.Bar.offsetTop + i);
//防止触发其他滚动条
e.preventDefault();
//绑定鼠标滚轮
WheelBind: function(o) {
//鼠标滚轮控制
addEventHandler(o, isIE ? "mousewheel" : "DOMMouseScroll", BindAsEventListener(this, this.WheelCtrl));
//方向键控制
KeyCtrl: function(e) {
if(this.KeySpeed){
var iLeft = this.Bar.offsetLeft, iWidth = (this.Container.clientWidth - this.Bar.offsetWidth) / this.KeySpeed
, iTop = this.Bar.offsetTop, iHeight = (this.Container.clientHeight - this.Bar.offsetHeight) / this.KeyS
//根据按键设置值
switch (e.keyCode) {
case 37 ://左
iLeft -= iW
case 38 ://上
iTop -= iH
case 39 ://右
iLeft += iW
case 40 ://下
iTop += iH
//不是方向按键返回
this.SetPos(iLeft, iTop);
//防止触发其他滚动条
e.preventDefault();
//绑定方向键
KeyBind: function(o) {
addEventHandler(o, "keydown", BindAsEventListener(this, this.KeyCtrl));
//设置tabIndex使设置对象能支持focus
o.tabIndex = -1;
//取消focus时出现的虚线框
isIE || (o.style.outline = "none");
//获取当前值
GetValue: function() {
//根据最大最小值和滑动百分比取值
return this.MinValue + this.GetPercent() * (this.MaxValue - this.MinValue);
//设置值位置
SetValue: function(value) {
//根据最大最小值和参数值设置滑块位置
this.SetPercent((value- this.MinValue)/(this.MaxValue - this.MinValue));
//获取百分比
GetPercent: function() {
//根据滑动条滑块取百分比
return this._horizontal ? this.Bar.offsetLeft / (this.Container.clientWidth - this.Bar.offsetWidth)
: this.Bar.offsetTop / (this.Container.clientHeight - this.Bar.offsetHeight)
//设置百分比位置
SetPercent: function(value) {
//根据百分比设置滑块位置
this.EasePos((this.Container.clientWidth - this.Bar.offsetWidth) * value, (this.Container.clientHeight - this.Bar.offsetHeight) * value);
//自动滑移(是否递增)
Run: function(bIncrease) {
this.Stop();
//修正一下bIncrease
bIncrease = !!bI
//根据是否递增来设置值
var percent = this.GetPercent() + (bIncrease ? 1 : -1) * this.RunStep / 100;
this.SetPos((this.Container.clientWidth - this.Bar.offsetWidth) * percent, (this.Container.clientHeight - this.Bar.offsetHeight) * percent);
//如果没有到极限值就继续滑移
if(!(bIncrease ? this._IsMax : this._IsMin)){
this._timer = setTimeout(Bind(this, this.Run, bIncrease), this.RunTime);
//停止滑移
Stop: function() {
clearTimeout(this._timer);
//缓动滑移
EasePos: function(iLeftT, iTopT) {
this.Stop();
//必须是整数,否则可能死循环
iLeftT = Math.round(iLeftT); iTopT = Math.round(iTopT);
//如果没有设置缓动
if(!this.Ease){ this.SetPos(iLeftT, iTopT); }
//获取缓动参数
var iLeftN = this.Bar.offsetLeft, iLeftS = this.GetStep(iLeftT, iLeftN)
, iTopN = this.Bar.offsetTop, iTopS = this.GetStep(iTopT, iTopN);
//如果参数有值
if(this._horizontal ? iLeftS : iTopS){
//设置位置
this.SetPos(iLeftN + iLeftS, iTopN + iTopS);
//如果没有到极限值则继续缓动
if(this._IsMid){ this._timer = setTimeout(Bind(this, this.EasePos, iLeftT, iTopT), this.RunTime); }
//获取步长
GetStep: function(iTarget, iNow) {
var iStep = (iTarget - iNow) / this.EaseS
if (iStep == 0) return 0;
if (Math.abs(iStep) & 1) return (iStep & 0 ? 1 : -1);
//设置滑块位置
SetPos: function(iLeft, iTop) {
this.Stop();
this._drag.SetPos(iLeft, iTop);
&script type="text/javascript" src="Drag.js"&&/script&
&p&预览效果1:&/p&
&style type="text/css"&
.container{width:600 background:#3E3E3E; overflow: color:# padding:10px 20}
.content{ overflow: margin-bottom:10width:600}
.content div{ width:130 margin:5 padding:5 padding-bottom:0; height:120 line-height:20 background-color:#000000;}
.content div img{ width:130 height:100 border:0;display:}
.slider{ padding:1px 0; position:background:#0A0A0A; height:15 border-bottom:1px solid #545454;border-top:1px solid #545454; float: width:544cursor: }
.slider_left, .slider_right{ background:url(http://pic002.cnblogs.com/img/cloudgamer/8.gif) no- height:19 width:28 float: cursor:}
.slider_left{background-position:}
.slider_right{background-position:}
.bar{ height:15 width:150 background:url(http://pic002.cnblogs.com/img/cloudgamer/0.gif) left top repeat-x;}
.bar_left, .bar_right{background:url(http://pic002.cnblogs.com/img/cloudgamer/8.gif) no-height:15 _font-size:0; width:6 position: top:0}
.bar_left{background-position:left:-6}
.bar_right{background-position:right:-6}
&div id="idContainer" class="container"&
&div id="idContent" class="content"&
&table cellpadding="0" cellspacing="0"&
&tr align="center"&
&td&&div&&a href="http://www.cnblogs.com/cloudgamer/archive//1247267.html"&&img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_rt_2.jpg" /&&/a&1. 图片切割&/div&&/td&
&td&&div&&a href="http://www.cnblogs.com/cloudgamer/archive//1236770.html"&&img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_rt_1.jpg" /&&/a&2. 图片切换展示&/div&&/td&
&td&&div&&a href="http://www.cnblogs.com/cloudgamer/archive//1205642.html"&&img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_rt_3.jpg" /&&/a&3. 图片变换效果&/div&&/td&
&td&&div&&a href="http://www.cnblogs.com/cloudgamer/archive//1314766.html"&&img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_rt_5.jpg" /&&/a&4. 无刷新上传&/div&&/td&
&td&&div&&a href="http://www.cnblogs.com/cloudgamer/archive//1194272.html"&&img src="http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_rt_4.jpg" /&&/a&5. 图片滑动展示&/div&&/td&
&div class="slider_left" id="idSliderLeft"&&/div&
&div class="slider" id="idSlider"&
&div class="bar" id="idBar"&
&div class="bar_left"&&/div&
&div class="bar_right"&&/div&
&div class="slider_right" id="idSliderRight"&&/div&
var sld = new Slider("idSlider", "idBar", {
MaxValue: $("idContent").scrollWidth - $("idContent").clientWidth,
onMin: function(){ $("idSliderLeft").style.backgroundPosition = "bottom left"; },
onMax: function(){ $("idSliderRight").style.backgroundPosition = "bottom right"; },
onMid: function(){ $("idSliderLeft").style.backgroundPosition = "top left"; $("idSliderRight").style.backgroundPosition = "top right"; },
onMove: function(){ $("idContent").scrollLeft = this.GetValue(); }
sld.SetPercent(.5);
sld.Ease =
$("idSliderLeft").onmouseover = function(){ sld.Run(false); }
$("idSliderLeft").onmouseout = function(){ sld.Stop(); }
$("idSliderRight").onmouseover = function(){ sld.Run(true); }
$("idSliderRight").onmouseout = function(){ sld.Stop(); }
&p&预览效果2:&/p&
&style type="text/css"&
.container2{width:425background:# border:1px solid #000000;}
.content2{ overflow:height:200width:400 _float: padding:2 padding-right:0; margin:0; line-height:1.5}
.slider2{height:200 width:18 background-color:# border:2px solid #EAE6DD; float:}
.bar2{width:14 border:2px ou background-color:#D4D0C8; _font-size:0;}
&div id="idContainer2" class="container2"&
&div id="idSlider2" class="slider2"&
&div id="idBar2" class="bar2"&&/div&
&ul id="idContent2" class="content2"&
&li&1. &a href="http://www.cnblogs.com/cloudgamer/archive//1247267.html"&JavaScript 图片切割效果&/a& &/li&
&li&2. &a href="http://www.cnblogs.com/cloudgamer/archive//1236770.html"&JavaScript 图片切换展示效果&/a& &/li&
&li&3. &a href="http://www.cnblogs.com/cloudgamer/archive//1205642.html"&JavaScript 图片变换效果(ie only)&/a& &/li&
&li&4. &a href="http://www.cnblogs.com/cloudgamer/archive//1290954.html"&JavaScript 仿LightBox内容显示效果&/a& &/li&
&li&5. &a href="http://www.cnblogs.com/cloudgamer/archive//1314766.html"&仿163网盘无刷新文件上传系统&/a& &/li&
&li&6. &a href="http://www.cnblogs.com/cloudgamer/archive//1194272.html"&JavaScript 图片滑动展示效果&/a& &/li&
&li&7. &a href="http://www.cnblogs.com/cloudgamer/archive//1231557.html"&JavaScript 自定义多级联动浮动菜单&/a& &/li&
&li&8. &a href="http://www.cnblogs.com/cloudgamer/archive//1277131.html"&JavaScript 渐变效果&/a& &/li&
&li&9. &a href="http://www.cnblogs.com/cloudgamer/archive//1303993.html"&图片切割系统&/a& &/li&
&li&10. &a href="http://www.cnblogs.com/cloudgamer/archive//1334778.html"&JavaScript 拖放效果&/a& &/li&
&li&11. &a href="http://www.cnblogs.com/cloudgamer/archive//1346386.html"&JavaScript 拖拉缩放效果&/a& &/li&
&li&12. &a href="http://www.cnblogs.com/cloudgamer/archive//1177682.html"&JavaScript 无缝上下左右滚动加定高定宽停顿效果&/a& &/li&
&li&13. &a href="http://www.cnblogs.com/cloudgamer/archive//1304414.html"&JavaScript Table排序&/a& &/li&
&li&14. &a href="http://www.cnblogs.com/cloudgamer/archive//1201386.html"&JavaScript 弹簧效果&/a& &/li&
&li&15. &a href="http://www.cnblogs.com/cloudgamer/archive//1274459.html"&JavaScript blog式日历控件&/a& &/li&
&li&16. &a href="http://www.cnblogs.com/cloudgamer/archive//1040403.html"&JavaScript 日期联动选择器&/a& &/li&
&li&17. &a href="http://www.cnblogs.com/cloudgamer/archive//1228736.html"&JavaScript 自定义多级联动下拉菜单&/a& &/li&
&li&18. &a href="http://www.cnblogs.com/cloudgamer/archive//1200705.html"&JavaScript 滑移效果&/a& &/li&
&li&19. &a href="http://www.cnblogs.com/cloudgamer/archive//1040404.html"&JavaScript 颜色渐变效果&/a& &/li&
$("idBar2").style.height = $("idSlider2").clientHeight * Math.min($("idContent2").clientHeight / $("idContent2").scrollHeight, 1) - 4 + "px";
var sld2 = new Slider("idSlider2", "idBar2", { Horizontal: false,
MaxValue: $("idContent2").scrollHeight - $("idContent2").clientHeight,
onMove: function(){ $("idContent2").scrollTop = this.GetValue(); }
sld2.WheelBind($("idContent2"));
sld2.KeyBind($("idContent2"));
&p&预览效果3:&/p&
&style type="text/css"&
.slider3{height:19 width:600 background-color:# border:2px solid #EAE6DD; margin:10px 0;}
.bar3 {height:15 width:10 border:2px ou background-color:#D4D0C8;_font-size:0; }
&div id="idSlider3" class="slider3"&
&div id="idBar3" class="bar3"&&/div&
&div id="idShow"& 当前值:&span id="idCurrentValue"&&/span&&br /&
当前百分比:&span id="idCurrentPercent"&&/span&%&br /&
状态:&span id="idCurrentState"&未开始&/span&&br /&
设置最小值:
&input id="txtMin" type="text" value="0" size="5" /&
设置最大值:
&input id="txtMax" type="text" value="100" size="5" /&
&input id="txtMove" type="text" value="50" size="5" /&
&input id="btnMoveV" type="button" value="按实际值" /&
&input id="btnMoveP" type="button" value="按百分比" /&
&input id="btnEase" type="button" value="设置缓动" /&
var sld3 = new Slider("idSlider3", "idBar3", {
onMin: function(){ $("idCurrentState").innerHTML = "到达开始值"; },
onMax: function(){ $("idCurrentState").innerHTML = "到达结束值"; },
onMid: function(){ $("idCurrentState").innerHTML = "滑动中"; },
onMove: function(){
$("idCurrentValue").innerHTML = Math.round(this.GetValue());
$("idCurrentPercent").innerHTML = Math.round(this.GetPercent() * 100);
$("txtMin").onchange = function(){ sld3.MinValue = parseInt($("txtMin").value, 10); }
$("txtMax").onchange = function(){ sld3.MaxValue = parseInt($("txtMax").value, 10); }
$("txtMin").onchange();
$("txtMax").onchange();
sld3.onMove();
$("btnMoveV").onclick = function(){ sld3.SetValue(parseInt($("txtMove").value, 10)); }
$("btnMoveP").onclick = function(){ sld3.SetPercent(parseInt($("txtMove").value, 10) / 100); }
$("btnEase").onclick = function(){
if(sld3.Ease){
sld3.Ease =
this.value = "设置缓动";
sld3.Ease =
this.value = "取消缓动";
转自:http://www.cnblogs.com/cloudgamer/archive//Slider.html
黑色头发:http://heisetoufa.iteye.com/
下载次数: 990
浏览 33207
heisetoufa
浏览: 9626266 次
来自: 北京
忽悠人的。这是web的。不是java的,也不是swing的。
document.wirte拼写错了。。document.wr ...
解决了一个文件加载问题,感谢
// 设置不持久化,此处学习,实际根据项目决定
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 vuejs 设置滚动条位置 的文章

 

随机推荐