自定义滚动条的还是个很简单的特效,不过给页面的外观改善。
注意的地方就是给要滚动的元素设置样式:overflow:hidden;position:absolute;,不能设置高度,通过元素的scrollHeight获取最终的高度,在减去显示的高度,设置元素的样式为0到负(scrollHeight-height)就能达到显示,再添加各种事件实现滚动,另外在拖动滚动条后,一定要记住当前滚动的位置,不然鼠标滚动会出现错误。
下面代码没有写成插件的形式,不过改写成插件还是很简单的。
<html>
<head>
<style type = "text/css">
.scr-border{overflow:hidden;position:relative;width:412px;height:200px;}
.sroll-bar{float:right;}
.scr-vertical-line{background:url(scroll/2.gif);width:12px;height:175px;}
.scr-vertical-button{width:12px;height:12px;}
.scr-vertical-top{background:url(scroll/1.gif)}
.scr-vertical-bottom{background:url(scroll/3.gif)}
.scr-vertival-img{position:absolute;top:12px;}
.scr-content{background-color:gray;width:400px;overflow:hidden;position:absolute;}
.scr-vertival-img{width:12px;height:20px;background:url(scroll/about_17.gif);}
</style>
<script type = "text/javascript">
var Scroller = function(options) {
this._options = options;
this._drag = false;
this._wheel = 0;
};
Scroller.prototype = {
init:function(){
var _content = document.getElementById(this._options.id);
var _border = document.getElementById('sroll-border');
this.content = _content;
this.border = _border;
var sliders = Util.findClass('scr-vertival-img', _border, 'div');
this.locate(sliders[0]);
},
locate : function(slider){
this._offsetHeight = this.content.scrollHeight;
this._height = parseInt(Util.getCss(this.border, 'height'));
this._gap = this._offsetHeight - this._height
var scrollHeight = parseInt(Util.getCss(Util.findClass('scr-vertical-line', this.border, 'div')[0], 'height')),
position = Util.getBox(slider);
this.add(slider, position, scrollHeight);
},
add : function (slider, position, scrollHeight){
var that = this, sliderHeight = position[3],
topY = position[1], bottomY = topY + scrollHeight - sliderHeight;
var _scrollHeight = scrollHeight - sliderHeight;
//点击向下拉动的事件
Util.addEvent(Util.findClass('scr-vertical-bottom')[0], 'click', function(){
move(-1);
});
//点击向上拉动的事件
Util.addEvent(Util.findClass('scr-vertical-top')[0], 'click', function(){
move(1);
});
//拖动时,鼠标按下事件
Util.addEvent(slider, 'mousedown', function(){
that._drag = true;
Util.addEvent(document, 'mousemove', scrollVertal);
});
//鼠标滚轮滑动事件
Util.addEvent(that.content, 'DOMMouseScroll', function(e){
var e = e || window.evnet, delta = 0;
if (e.wheelDelta) { /* IE/Opera. */
delta = e.wheelDelta / 120;
} else if (e.detail) {
delta = -e.detail / 3;
}
move(delta);
});
//鼠标松开事件
Util.addEvent(document, 'mouseup', function(){
if (that._drag){
//在拖动结束后,记录当前滑动的位置
var current = parseInt(Util.getCss(slider, 'top'));
that._wheel = Math.round(10 * current / (scrollHeight - 20));
}
that._drag = false;
Util.removeEvent(document, 'mousemove', scrollVertal);
});
//鼠标滑动,总共10格
function move(delta){
that._wheel < 0 && (that._wheel = 0);
that._wheel > 10 && (that._wheel = 10);
that._wheel -= delta;
if(that._wheel >= 0 && that._wheel <= 10){
var wheelheight = that._wheel * (that._gap - 12) / 10;
that.bodyScroll(wheelheight);
slider.style.top = (12 + (that._wheel * (scrollHeight - 20)) / 10) + 'px';
}
}
//当前鼠标位置
function mousePosition(e){
if(e.pageX || e.pageY)
return {x:e.pageX, y:e.pageY};
return {
x:e.clientX + document.body.scrollLeft - document.body.clientLeft,
y:e.clientY + document.body.scrollTop - document.body.clientTop
};
}
//拖动时事件
function scrollVertal(e){
var e = e || window.event;
var position = mousePosition(e),
y = position.y;
if (that._drag && y >= topY && y <= bottomY){
var _offset = y - topY + sliderHeight/2;
slider.style.top = _offset + 'px';
that.bodyScroll((_offset - 12 ) / _scrollHeight * that._gap);
}
}
},
bodyScroll : function(_offsetTop){
//Util.setCss(this.content, {top : ('-' + _offsetTop + 'px')});
this.content.style.top = '-' + parseInt(_offsetTop) + 'px';
}
};
var Util = {
//添加事件
addEvent : function (o, t, f) {
if (o.addEventListener) o.addEventListener(t, f, false);
else if (o.attachEvent) o.attachEvent('on'+ t, f);
else o['on'+ t] = f;
},
//移除事件
removeEvent : function (o, t, f) {
if (o.removeEventListener) o.removeEventListener(t, f, false);
else if (o.detachEvent) o.detachEvent('on'+ t, f);
else o['on'+ t] = null;
},
//得到样式的值
getCss : function (elem, styles) {
var value;
if (styles == 'float')
styles = document.defaultView && document.defaultView.getComputedStyle?styles:'styleFloat';
if (document.defaultView && document.defaultView.getComputedStyle)
value = document.defaultView.getComputedStyle(elem, null).getPropertyValue(styles);
else {
styles = camelize(styles);
value = (styles == 'opacity') ? /opacity=([^)]*)/.test(elem.currentStyle["filter"]) ? (parseFloat(RegExp.$1) * 0.01) : 1 : elem.currentStyle[styles];
}
if ((value == "auto" || value.toString().indexOf("%") >= 0) && filters(["width", "height"], styles))
value = elem["offset" + capitalize(styles)] + "px";
return value;
},
//设置元素的样式
setCss : function (elem, name, value) {
if(arguments.length == 2) {
if(typeof name == "string")
elem.style.cssText = name;
else
for(var property in name)
myStyle(elem, property, name[property]);
}else
myStyle(elem,name,value);
function myStyle (elem, name, value){
if(name == 'float')
name = document.defaultView && document.defaultView.getComputedStyle ? 'cssFloat' : 'styleFloat';
if(name = 'opacity')
elem.style.filter = 'alpha(opacity=' + value * 100+ ')';
else
elem.style[camelize(name)] = value;
}
},
//根据样式获取对象
findClass : function (name, root, tag) {
root = root || document;
tag = tag || '*';
var i = 0, elements = root.getElementsByTagName(tag),
len = elements.length, collections = [],
reg = new RegExp('(^|\\s)' + name + '(\\s|$)');
for (;i < len ; i++)
reg.test(elements[i].className) && collections.push(elements[i]);
return collections;
},
getBox : function(el){
var x = y = 0, tmp =el;
do {
x += tmp.offsetLeft;
y += tmp.offsetTop;
}while(tmp = tmp.offsetParent);
return [x,y,el.offsetWidth,el.offsetHeight];
}
};
//首字母大写 width返回Width
function capitalize (args) {
return args.charAt(0).toUpperCase()+args.substr(1).toLowerCase();
}
//判断数组是否包含该元素
function filters (arr, value) {
return arr.toString().indexOf(value)>=0;
}
//margin-top变为marginTop
function camelize (param) {
return param.replace(/-(\w)/, function ($1, $2) {
return $2.toUpperCase();
});
}
</script>
</head>
<body>
<p>swgfas</p>
<p>swgfas</p>
<p>swgfas</p>
<div class = "scr-border" id ="sroll-border">
<div class = "sroll-bar">
<div class = "scr-vertical-top scr-vertical-button"></div>
<div class = "scr-vertical-line">
<div class = "scr-vertival-img">
</div>
</div>
<div class = "scr-vertical-bottom scr-vertical-button"></div>
</div>
<div class = "scr-content" id ="sroll-content">
<!--
这里面是滚动条的内容
-->
<p>
111
</p>
<p>
222
</p>
<p>
333
</p>
<p>
444
</p>
<p>
555
</p>
<p>
666
</p>
<p>
777
</p>
<p>
888
</p>
<p>
999
</p>
</div>
</div>
</body>
<script type = "text/javascript">
var b = {id : 'sroll-content'};
var aa = new Scroller(b);
aa.init();
</script>
</html>