您的位置:首页 > Web前端 > JavaScript

javascript 实现的scrollbar 兼容ff/chrome/IE

2014-10-14 18:08 609 查看
在javascript基础类的基础上实现。实现垂直滚动条。

1 改进拖动条计算方式

/*node 为需要滚动展示的控件ID 控件会根据其父容器自动设定宽度 不支持resize只能初始化一次 */
GLOBAL.Component.TinyVScrollBar = function (nodeID) {
this._nodeID = nodeID;
this._wrapList = GLOBAL.Dom.get(this._nodeID);
if (typeof (this._wrapList) == 'undefined')
return;
this._wrapBox = this._wrapList.parentNode;
this._scrollBox = null;
this._scrollBar = null;
this._scrollBoxID = this._nodeID + "scrollBox";
this._scrollBarID = this._nodeID + "scrollBar";
this._scale = 0;
this._height = 0;
this._maxTop = 0;
this._ListMaxTop = 0;
this._top = 0;
/*供事件所用*/
this._disY = 0;
this._EventMap = {};
this._bNegNumber = 0;
this._ddisY = 0;
/*初始化显示*/
if(this.init() == 0)
{
return;
}
/*初始化移动高度*/
this.initScale();
/*绑定事件*/
this.bindEvent();
}

GLOBAL.Component.TinyVScrollBar.prototype.init = function () {
/*创建div*/
this._scrollBox = document.createElement("div");
this._scrollBox.id = this._scrollBoxID;
this._scrollBox.className = "js-scrollbox";
this._scrollBox.style.height = this._wrapBox.style.height;
this._scrollBar = document.createElement("div");
this._scrollBar.id = this._scrollBarID;
this._scrollBar.className = "js-scrollbar";
this._scrollBox.appendChild(this._scrollBar);
this._wrapBox.appendChild(this._scrollBox);
/*设定宽度 及位置 */
/*父容器position必须为absolute 或者为 relative*/
GLOBAL.Dom.setStyle(this._wrapBox, { 'overflow': 'hidden' });
/*设置wraplist的位置和宽度*/
var v_listWidth = this._wrapBox.clientWidth - 15;
GLOBAL.Dom.setStyle(this._wrapList, { 'position': 'absolute', 'top': '0px', 'left': '0px', 'width': v_listWidth + 'px' });
GLOBAL.Dom.setAttribute(this._wrapBox, { 'tabIndex': 0 });
/*设置scrollbox*/
GLOBAL.Dom.setStyle(this._scrollBox, { 'position': 'absolute', 'top': '0px', 'left': v_listWidth + 'px' });
if (GLOBAL.TOOL.getNodeClientSize(this._wrapList).h <= GLOBAL.TOOL.getNodeClientSize(this._wrapBox).h)
{
GLOBAL.Dom.setStyle(this._scrollBox, { 'display': 'none'});
GLOBAL.Dom.setStyle(this._wrapList, {'width': this._wrapBox.clientWidth + 'px' });
return 0;
}
return 1;
}

GLOBAL.Component.TinyVScrollBar.prototype.updateScroll = function () {
this.clearAll();
this._wrapList = GLOBAL.Dom.get(this._nodeID);
if (typeof (this._wrapList) == 'undefined')
return;
this._wrapBox = this._wrapList.parentNode;
if (GLOBAL.TOOL.getNodeSize(this._wrapList).h <= GLOBAL.TOOL.getNodeSize(this._wrapBox).h)
return;
this._top = 0;
this.init();
/*初始化移动高度*/
this.initScale();
this.bindEvent();

}

GLOBAL.Component.TinyVScrollBar.prototype.clearAll = function () {
this.clearEvent();
var node = GLOBAL.Dom.get(this._scrollBarID);
if (node)
node.parentNode.removeChild(node);
node = GLOBAL.Dom.get(this._scrollBoxID);
if (node)
node.parentNode.removeChild(node);
}

GLOBAL.Component.TinyVScrollBar.prototype.clearEvent = function () {
if (this._EventMap != null) {
var key, comArray, tmp;
for (key in this._EventMap) {
comArray = key.split('$');
if (this._EventMap[key] == null)
continue;
if (comArray.length >= 2) {
tmp = comArray[0];
if (tmp.indexOf('_') >= 0) {
eval('GLOBAL.Event.remove(this.' + GLOBAL.TOOL.trim(comArray[0]) + ',"' + GLOBAL.TOOL.trim(comArray[1]) + '",this._EventMap["' + key + '"]);');
} else {
eval('GLOBAL.Event.remove(' + GLOBAL.TOOL.trim(comArray[0]) + ',"' + GLOBAL.TOOL.trim(comArray[1]) + '",this._EventMap["' + key + '"]);');
}
}
}
}
};

GLOBAL.Component.TinyVScrollBar.prototype.initScale = function () {
this._scale = this._wrapBox.clientHeight / this._wrapList.scrollHeight;
this._height = this._scale * this._scrollBox.clientHeight;
this._maxTop = this._scrollBox.clientHeight - this._height;
this._ListMaxTop = this._wrapBox.clientHeight - this._wrapList.scrollHeight;
this._scrollBar.style.height = this._height + 'px';
}
GLOBAL.Component.TinyVScrollBar.prototype.fnScroll = function () {
if (this._top < 0) this._top = 0;
if (this._top > this._maxTop) this._top = this._maxTop;
var scale = this._top / this._maxTop;
var listTop = scale * this._ListMaxTop;
this._scrollBar.style.top = this._top + 'px';
this._wrapList.style.top = listTop + 'px';
}
GLOBAL.Component.TinyVScrollBar.prototype.bindEvent = function () {
/*绑定滑轮事件*/
this._EventMap._wrapList$mousewheel = GLOBAL.Event.on(this._wrapBox, 'mousewheel', this.mousewheel, this);
this._EventMap._wrapList$DOMMouseScroll = GLOBAL.Event.on(this._wrapBox, 'DOMMouseScroll', this.mousewheel, this);
/*单击事件*/
this._EventMap._scrollBox$click = GLOBAL.Event.on(this._scrollBox, 'click', this.mouseclick, this);
this._EventMap._scrollBar$click = GLOBAL.Event.on(this._scrollBar, 'click', this.mousecancelclick, this);
/*单击拖动事件*/
this._EventMap._scrollBar$mousedown = GLOBAL.Event.on(this._scrollBar, 'mousedown', this.mousemoveanddown, this);
/*鼠标双击事件*/
this._EventMap._scrollBar$dblclick = GLOBAL.Event.on(this._scrollBar, 'dblclick', this.mousedbclick, this);
/*键盘事件*/
this._EventMap._wrapBox$keydown = GLOBAL.Event.on(this._wrapBox, 'keydown', this.keyDown, this);
/*选择事件*/
this._EventMap._wrapList$mousedown = GLOBAL.Event.on(this._wrapBox, 'mousedown', this.mousedown, this);
}
/*定义的事件*/
/*鼠标滑轮*/
GLOBAL.Component.TinyVScrollBar.prototype.mousewheel = function (ev) {
ev = ev || event;
var fx = ev.wheelDelta || ev.detail;
var bDown = true;
if (ev.detail) {
bDown = fx > 0 ? true : false;
} else {
bDown = fx > 0 ? false : true;
}
if (bDown) {
this._top += 10;
} else {
this._top -= 10;
}
this.fnScroll();
GLOBAL.Event.stopPropagation(ev);
};
/*单击事件*/
GLOBAL.Component.TinyVScrollBar.prototype.mouseclick = function (ev) {
ev = ev || event;
var position = GLOBAL.TOOL.getWindowPosition(this._scrollBox);
var disY = ev.clientY - position.y;
this._top = disY - GLOBAL.TOOL.parsePx(this._scrollBar.style.height) / 2;
this.fnScroll();
GLOBAL.Event.stopPropagation(ev);
};
GLOBAL.Component.TinyVScrollBar.prototype.mousecancelclick = function (ev) {
ev = ev || event;
GLOBAL.Event.stopPropagation(ev);
};

/*单击拖动事件*/
GLOBAL.Component.TinyVScrollBar.prototype.mousemoveanddown = function (ev) {
ev = ev || event;
//console.debug("mousemoveanddown");
//var position = GLOBAL.TOOL.getWindowPosition(this._scrollBox);
this._disY = ev.clientY;
//console.debug("a"+this._disY);
this._EventMap.document$mousemove = GLOBAL.Event.on(document, 'mousemove', this.documentmousemove, this);
this._EventMap.document$mouseup = GLOBAL.Event.on(document, 'mouseup', this.documentmousemovecancel, this);
GLOBAL.Event.stopPropagation(ev);
};
GLOBAL.Component.TinyVScrollBar.prototype.documentmousemove = function (ev) {
ev = ev || event;
//console.debug("b"+ev.clientY);
var topY = ev.clientY - this._disY;
this._disY = ev.clientY;
this._top += topY;
this.fnScroll();
GLOBAL.Event.stopPropagation(ev);
};
GLOBAL.Component.TinyVScrollBar.prototype.documentmousemovecancel = function (ev) {
ev = ev || event;
if (this._EventMap.document$mousemove) {
GLOBAL.Event.remove(document, 'mousemove', this._EventMap.document$mousemove);
}
if (this._EventMap.document$mouseup) {
GLOBAL.Event.remove(document, 'mouseup', this._EventMap.document$mouseup);
}
GLOBAL.Event.stopPropagation(ev);
};
/*鼠标双击事件*/
GLOBAL.Component.TinyVScrollBar.prototype.mousedbclick = function (ev) {

ev = ev || event;
if (this._bNegNumber == 0) {
this._top += 10;
if (this._top < 0) this._top = 0;
if (this._top >= this._maxTop) {
this._top = this._maxTop;
this._bNegNumber = 1;
}
}
else {
this._top -= 10;
if (this._top <= 0) {
this._top = 0;
this._bNegNumber = 0;
}
if (this._top >= this._maxTop) {
this._top = this._maxTop;
}
}
this.fnScroll();
GLOBAL.Event.stopPropagation(ev);
};
/*键盘事件*/
GLOBAL.Component.TinyVScrollBar.prototype.keyDown = function (e) {
e = GLOBAL.Event.getEvent(e);
var currKey = e.keyCode || e.which || e.charCode;
switch (currKey) {
case 38: //向上
this._top -= 10;
if (this._top < 0) this._top = 0;
break;
case 40: //向下
this._top += 10;
if (this._top > this._maxTop) this._top = this._maxTop;
break;
default:
}
this.fnScroll();
GLOBAL.Event.stopPropagation(e);
}
GLOBAL.Component.TinyVScrollBar.prototype.mouseup = function (ev) {
if (this._EventMap.document$mousemove$wraplist) {
GLOBAL.Event.remove(document, 'mousemove', this._EventMap.document$mousemove$wraplist);
}
if (this._EventMap.document$mouseup$wraplist) {
GLOBAL.Event.remove(document, 'mouseup', this._EventMap.document$mouseup$wraplist);
}
GLOBAL.Event.stopPropagation(ev);
}

GLOBAL.Component.TinyVScrollBar.prototype.mousedown = function (ev) {
ev = ev || event;
this._ddisY = ev.clientY;
this._EventMap.document$mousemove$wraplist = GLOBAL.Event.on(document, 'mousemove', this.wraplistdocumentmousemove, this);
this._EventMap.document$mouseup$wraplist = GLOBAL.Event.on(document, 'mouseup', this.mouseup, this);
GLOBAL.Event.stopPropagation(ev);
}

GLOBAL.Component.TinyVScrollBar.prototype.wraplistdocumentmousemove = function (ev) {
ev = ev || event;
//console.debug("b"+ev.clientY);
var position = GLOBAL.TOOL.getWindowPosition(this._wrapBox);
if (ev.clientY > position.y && ev.clientY < (position.y + this._wrapBox.clientHeight)) {
GLOBAL.Event.stopPropagation(ev);
return;
}
var topY = ev.clientY - this._ddisY;
if (topY == 0) {
GLOBAL.Event.stopPropagation(ev);
return;
}
if (topY < 0) {
this._ddisY = ev.clientY;
this._top -= 10;
}
else {
this._ddisY = ev.clientY;
this._top += 10;
}
this.fnScroll();
GLOBAL.Event.stopPropagation(ev);
}


所使用的css

.js-scrollbar:hover{
border: 0.5px #0036ff solid ;
background-color: #494949;
box-shadow: inset 0 0.5px rgba(255,255,255,0.36),0 0 0 1px #6fb5f1;
cursor:pointer;
}

.js-scrollbar{
position:relative;
width:13px;
height:20px;
margin-left:auto;
margin-right:auto;
background-color: #d9d9d9;
border-radius: 2px;
}

.js-scrollbox{
width:15px;
border-radius: 2px;
background-color: #f3faff;
}


使用为获取要显示的div 的ID, new GLOBAL.Component.TinyVScrollBar("#divID");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: