这是过年的时候自己写的js滚动条插件的源码,做出的效果自己并不满意,正因为做的并不满意所以回头重新巩固和深入学习js,这个插件有如下几个不太满意的地方:
内容的过度效果,可以参阅QQ客户端最近会话列表里的滚动条,它的滚动非常的平滑,简单的说就是缺少动画过渡效果。
并不算完美的兼容性,在IE6、7下的style仍然有点缺憾。
样式的不完美,例如鼠标悬浮才显示滚动条,移除后隐藏这种效果都没有写。
内部结构的混乱,需要调整内容结构。
滚动条那个图片毕竟不是美工,自己切图切的真是恶心到爆了...囧
总体来说还是可以看的,还是缺少一个动画。在写这个插件意识到自己的插件用到了一些比较基础的函数,于是想到把这些函数应该封装起来,最近仍然在深入学习js,把手头上这本书看完就应该着手写这个基础函数的插件了,当然,动画引擎必不可少。话不多说,源码在此(注意:本插件完整版的是有图片的,请在文末附件中下载完整的插件):
CSS
代码如下:
.lf_Scroll, .lf_Scroll li { padding: 0; margin: 0; list-style: none; font: 14px/24px "Helvetica Neue" ,Helvetica,Arial, 'Microsoft Yahei' ,sans-serif; outline: none; }
.lf_Scroll { cursor: pointer; width: 10px; position: absolute; right: 0; top: 0; filter: alpha(opacity=50); -moz-opacity: 0.5; -khtml-opacity: 0.5; opacity: 0.5; }
.lf_ScrollFocus { filter: alpha(opacity=100); -moz-opacity: 1; -khtml-opacity: 1; opacity: 1; }
.lfs_Top, .lfs_Center, .lfs_Bottom { background: url('ScrollBar.gif'); width: 10px; height: 10px; }
.lfs_Top { background-position: 1px 0px; }
.lfs_Center { background-position: center 0; height: 100px; }
.lfs_Bottom { background-position: -22px 0; }
/*Developers config*/
.rollDiv { height: 100%; width: 100%; overflow: hidden; position: relative; }
JavaScript
代码如下:
/*
* This plugin is defined on the simulation Webpage scroll bar, please insert after binding for DOM events
*
* Comment version: 1.0.0
* Author:linkfly
* Sina:为你聚焦半世纪 | cnblogs:http://www.cnblogs.com/silin6/ | Email:
[email protected]
* date:2014-02-05 02:38:35
*
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
(function (window, undefined) {
//配置参数信息
var config = {
auto: true,
height: 'auto',
width: 'auto'
};
var linkFlyScroll = function (dom, options) {
/// <summary>
/// 1: 生成模拟滚动条对象,【请在本对象工作之后再为您指定的对象绑定事件,否则您之前绑定的事件将不会进行工作】
/// 1.1 - linkFlyScroll(dom) - 在指定的dom上生成滚动条对象
/// 1.2 - linkFlyScroll(dom,options) - 生成滚动条对象,同时提供一系列的参数允许您自定义配置该对象的工作模型
/// </summary>
/// <param name="dom" type="String Or element">
/// 传入js的dom对象,或者为string类型的该对象ID
/// </param>
/// <param name="options" type="Json">
/// 自定义配置该对象的工作模型,有如下选项:
/// [可选]auto(Boolean):当内容并未达到容器的高度的时候,是否自动隐藏滚动条,默认为true(是)
/// [可选]height(Int Or String):默认单位为px,可以为int和String.值为auto则默认采用css的高度
/// [可选]width(Int Or String):默认单位为px,可以为int和String.值为auto则默认采用css的宽度
/// </param>
/// <returns type="linkFlyScroll" />
if (typeof (dom) === 'string') {
dom = document.getElementById(dom);
}
//没有指定dom和没有查找到有效的dom
//linkFlyScroll("")、 linkFlyScroll(null)、linkFlyScroll(undefined)
if (!dom || !dom.nodeType)
return this;
//创建容器对象
var scrollObj = document.createElement('div');
//深度克隆内容对象,并未包含事件,所以需要等到linkFlyScroll对象工作完毕后才可以为该dom对象绑定事件
var cloneObj = dom.cloneNode(true);
scrollObj.className = 'rollDiv';
scrollObj.appendChild(cloneObj);
//替换页面上当前对象
dom.parentNode.replaceChild(scrollObj, dom);
return new linkFlyScroll.prototype.init(scrollObj, options ? options : {});
};
linkFlyScroll.prototype.init = function (dom, options) {
/// <summary>
/// 1: 本对象才是真正意义上工作的对象,特殊的工作方式是因为可能存在linkFlyScroll的静态调用和实例化调用
/// 1.1 - init(dom,options) - 在指定的dom上生成滚动条对象
/// </summary>
/// <param name="dom" type="element">
/// dom对象
/// </param>
/// <param name="options" type="Json">
/// 自定义配置该对象的工作模型,有如下选项:
/// [可选]auto(Boolean):当内容并未达到容器的高度的时候,是否自动隐藏滚动条,默认为true(是)
/// [可选]height(Int Or String):默认单位为px,可以为int和String.值为auto则默认采用css的高度
/// [可选]width(Int Or String):默认单位为px,可以为int和String.值为auto则默认采用css的宽度
/// </param>
/// <returns type="linkFlyScroll" />
/*
* 本对象包含以下属性:
* isDrag:是否正在拖拽滚动条
* startTop:(工作中)滚动条开始滚动位置
* endTop:(工作中)滚动条结束滚动位置
* topLimit:滚动条顶部极限位置
* bottomLimit:滚动条底部极限位置
* context:内容Dom
* scrollRadix:滚动基数
* target:容器Dom
*/
//当前this对象,为防止this指针在环境中会经常改变(例如绑定事件的时候),所以将当前对象保存起来
var currScroll = this;
//DOMElement
if (dom.nodeType) {
//保存容器和内容DOM
currScroll.target = dom;
currScroll.context = dom.firstChild;
//合并配置参数
currScroll.options = tool.extend(config, options);
if (currScroll.options.width !== 'auto') {
dom.style.width = tool.convertValue(currScroll.options.width);
}
if (currScroll.options.height !== 'auto') {
dom.style.height = tool.convertValue(currScroll.options.height);
}
//查找到有效的dom
while (currScroll.context.nodeType != 1) {
currScroll.context = currScroll.context.nextSibling;
}
//创建滚动条dom
currScroll.scrollUl = document.createElement('ul');
currScroll.scrollUl.className = 'lf_Scroll';
currScroll.scrollUl.appendChild(tool.setClass('li', 'lfs_Top'));
currScroll.scrollUl.appendChild(tool.setClass('li', 'lfs_Center'));
currScroll.scrollUl.appendChild(tool.setClass('li', 'lfs_Bottom'));
currScroll.context.style.position = 'relative';
//先呈现在页面上才可以读取位置数据
dom.appendChild(currScroll.scrollUl);
this.change();
tool.addScrollEvent(currScroll.context, function (e) {
//绑定鼠标滚轮事件,3px滚动单位
if (e.wheel > 0) {//滚轮向上滚动
var currTop = currScroll.endTop -= 3;
currScroll.scrollEvent.call(currScroll, currTop);
} else {//滚轮向下滚动
var currTop = currScroll.endTop += 3;
currScroll.scrollEvent.call(currScroll, currTop);
}
});
//需要处理禁止文字在拖动的时候被选中 TODO
//鼠标点下事件,需要判断是否是左键点击,目前右键也会实现滚动 TODO
tool.addEvent(currScroll.scrollUl, 'mousedown', function (e) {
mouseDown.call(currScroll, e);
});
//追加事件,为了更好的用户体验在body上实现监听
tool.addEvent(document.body, 'mousemove', function (e) {
if (currScroll.isDrag) {
//获取当前鼠标位置
var position = tool.getMousePos(e);
//当前滚动条top位置
var currTop = (currScroll.endTop + position.y - currScroll.startTop);
//call是为了让this指针