分享一则JavaScript滚动条插件源码

内容摘要
这是过年的时候自己写的js滚动条插件的源码,做出的效果自己并不满意,正因为做的并不满意所以回头重新巩固和深入学习js,这个插件有如下几个不太满意的地方:
内容的过度效果,可以
文章正文

这是过年的时候自己写的js滚动条插件的源码,做出的效果自己并不满意,正因为做的并不满意所以回头重新巩固和深入学习js,这个插件有如下几个不太满意的地方:

内容的过度效果,可以参阅QQ客户端最近会话列表里的滚动条,它的滚动非常的平滑,简单的说就是缺少动画过渡效果。

并不算完美的兼容性,在IE6、7下的style仍然有点缺憾。

样式的不完美,例如鼠标悬浮才显示滚动条,移除后隐藏这种效果都没有写。

内部结构的混乱,需要调整内容结构。

滚动条那个图片毕竟不是美工,自己切图切的真是恶心到爆了...囧

总体来说还是可以看的,还是缺少一个动画。在写这个插件意识到自己的插件用到了一些比较基础的函数,于是想到把这些函数应该封装起来,最近仍然在深入学习js,把手头上这本书看完就应该着手写这个基础函数的插件了,当然,动画引擎必不可少。话不多说,源码在此(注意:本插件完整版的是有图片的,请在文末附件中下载完整的插件):

CSS

\\s|$)"))) {
                return true;
            }
            return false;
        },
        addClass: function (element, className) {
            /// <summary>
            ///     1: 为元素【追加】class
            ///         1.1 - addClass(element,className) - 为元素【追加】class,并返回修改后的class
            /// </summary>
            /// <param name="element" type="Element Or String">
            ///     节点对象
            /// </param>
            /// <param name="className" type="String">
            ///     Class Name
            /// </param>
            /// <returns type="Element" />
            if (!tool.hasClass(element, className)) {
                if (element.className.length < 1) {
                    element.className = className;
                } else {
                    element.className += ' ' + className;
                }
            }
            return element;
        },
        removeClass: function (element, className) {
            /// <summary>
            ///     1: 为元素移除class
            ///         1.1 - addClass(element,className) - 为元素移除class,并返回修改后的class
            /// </summary>
            /// <param name="element" type="Element Or String">
            ///     节点对象
            /// </param>
            /// <param name="className" type="String">
            ///     Class Name
            /// </param>
            /// <returns type="Element" />
            if (tool.hasClass(element, className)) {
                var reg = new RegExp("(^|\\s)" + className + "(\\s|$)");
                element.className = element.className.replace(reg, '');
            }
            return element;
        },
        css: function (element, key) {
            /// <summary>
            ///     1: 获取元素css指定的属性值
            ///         1.1 - css(element,className) - 获取元素css指定的属性值
            /// </summary>
            /// <param name="element" type="Element Or String">
            ///     节点对象
            /// </param>
            /// <param name="key" type="String">
            ///     要获取的css属性
            /// </param>
            /// <returns type="String" />
            return element.currentStyle ? element.currentStyle[key] : document.defaultView.getComputedStyle(element, false)[key];
        },
        addEvent: function (element, type, fn) {
            /// <summary>
            ///     1: 为元素追加事件
            ///         1.1 - css(element, type, fn) - 为元素追加事件,函数中this指向事件源
            /// </summary>
            /// <param name="element" type="Element Or String">
            ///     节点对象
            /// </param>
            /// <param name="type" type="String">
            ///     追加的事件名,不含字符on
            /// </param>
            /// <param name="fn" type="Function">
            ///     事件对象
            /// </param>
            /// <returns type="void" />
            if (element.attachEvent) {
                element['e' + type + fn] = fn;
                element[type + fn] = function () { element['e' + type + fn](window.event); }
                element.attachEvent('on' + type, element[type + fn]);
            } else if (element.addEventListener) {
                element.addEventListener(type, fn, false);
            }
        },
        //        removeEvent: function (element, type, fn) {
        //            /// <summary>
        //            ///     1: 为元素删除事件,本函数并未用到
        //            ///         1.1 - removeEvent(element, type, fn) - 为元素删除事件
        //            /// </summary>
        //            /// <param name="element" type="Element Or String">
        //            ///     节点对象
        //            /// </param>
        //            /// <param name="type" type="String">
        //            ///     删除的事件名
        //            /// </param>
        //            /// <param name="key" type="String">
        //            ///     删除的事件的函数名
        //            /// </param>
        //            /// <returns type="void" />
        //            if (element.detachEvent) {
        //                element.detachEvent('on' + type, element[type + fn]);
        //                element[type + fn] = null;
        //            } else if (element.removeEventListener) {
        //                element.removeEventListener(type, fn, false);
        //            }
        //        },
        addScrollEvent: function (element, fn) {
            /// <summary>
            ///     1: 追加ScrollEvent事件
            ///         1.1 - addScrollEvent(element,fn) - 在元素上追加ScrollEvent事件(特殊事件,在元素上鼠标滚轮滚动事件)
            /// </summary>
            /// <param name="element" type="Element Or String">
            ///     元素节点
            /// </param>
            /// <param name="fn" type="Function">
            ///     事件方法
            /// </param>
            /// <returns type="void" />
            var bindScrollFn = function (e) {
                e = e || window.event;
                //判断滚轮滚动方向:Firefox和其他浏览器不同
                e.wheel = (e.wheelDelta ? e.wheelDelta : -e.detail) > 0 ? 1 : -1; // 通过事件判断鼠标滚轮反向,1是向上,-1是向下
                //阻止浏览器默认行为
                if (e.preventDefault) { //ff
                    e.preventDefault();
                } else {
                    e.returnValue = false; //ie
                }
                fn.call(element, e);
            }
            if (document.addEventListener) {
                //ff
                element.addEventListener('DOMMouseScroll', bindScrollFn, false);
                //w3c
                element.addEventListener('mousewheel', bindScrollFn, false);
            } else//ie
            {
                element.attachEvent('onmousewheel', bindScrollFn);
            }
        },
        getEvent: function () {
            /// <summary>
            ///     1: 获取Event对象
            ///         1.1 - getEvent() - 在无参数的情况下获取Event对象,同时兼容性处理IE和FF
            /// </summary>
            /// <returns type="Event" />
            if (document.all) {
                return window.event;
            }
            func = getEvent.caller;
            while (func != null) {
                var arg0 = func.arguments[0];
                if (arg0) {
                    if ((arg0.constructor == Event || arg0.constructor == MouseEvent) || (typeof (arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) {
                        return arg0;
                    }
                }
                func = func.caller;
            }
            return null;
        },
        getMousePos: function (ev) {
            /// <summary>
            ///     1: 获取当前鼠标坐标
            ///         1.1 - getMousePos(ev) - 获取当前鼠标坐标,兼容性处理,返回的对象格式:{ x:鼠标x坐标 , y:鼠标y坐标 }
            /// </summary>
            /// <param name="ev" type="Event">
            ///     Event事件对象
            /// </param>
            /// <returns type="Json" />
            if (!ev) {
                ev = currScroll.getEvent();
            }
            if (ev.pageX || ev.pageY) {
                return {
                    x: ev.pageX,
                    y: ev.pageY
                };
            }
            if (document.documentElement && document.documentElement.scrollTop) {
                return {
                    x: ev.clientX + document.documentElement.scrollLeft - document.documentElement.clientLeft,
                    y: ev.clientY + document.documentElement.scrollTop - document.documentElement.clientTop
                };
            }
            else if (document.body) {
                return {
                    x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
                    y: ev.clientY + document.body.scrollTop - document.body.clientTop
                };
            }
        },
        extend: function (oldObj, newObj) {
            /// <summary>
            ///     1: 将两个对象进行合并
            ///         1.1 - extend(oldObj,newObj) - 将两个对象合并,并返回合并后的对象,采用clone的方式实现,所以不会对两个对象产生任何影响
            /// </summary>
            /// <param name="oldObj" type="Object">
            ///     要合并的对象A,该对象作为基础对象,将新对象的同名属性覆盖到基础对象中
            /// </param>
            /// <param name="newObj" type="Object">
            ///     要合并的对象B
            /// </param>
            /// <returns type="Object" />
            var tempObj = tool.clone(oldObj);
            for (var key in newObj) {
                if (newObj.hasOwnProperty(key) && !tempObj.hasOwnProperty(key)) {
                    tempObj[key] = newObj[key];
                }
            }
            return tempObj;
        },
        clone: function (obj) {
            /// <summary>
            ///     1: 克隆一个对象
            ///         1.1 - clone(obj) - 克隆一个对象,并返回克隆后的新对象,该对象的原型是被克隆的对象
            /// </summary>
            /// <param name="obj" type="Object">
            ///     要克隆的对象
            /// </param>
            /// <returns type="Object" />
            function Clone() { }
            Clone.prototype = obj;
            var newObj = new Clone();
            for (var key in newObj) {
                if (typeof newObj[key] == "object") {
                    newObj[key] = tool.clone(newObj[key]);
                }
            }
            return newObj;
        },
        convertValue: function (value) {
            /// <summary>
            ///     1: 将数值转换为有效的数值
            ///         1.1 - convertValue(value) - 将Json配置的css数值转换为有效的数值,请保证value的值不为"auto"
            /// </summary>
            /// <param name="value" type="Object">
            ///     要转换的数值
            /// </param>
            /// <returns type="Object" />
            var reg = /^\d+$/g;
            if (typeof (value) === 'number' || reg.test(value)) {
                return value + 'px';
            } else
                return value;
        }
    };
    //注册到window下
    window.linkFlyScroll = linkFlyScroll;
    //注册到window.so命名空间下
    if (!window.so) {
        window.so = {};
    }
    window.so.scroll = window.linkFlyScroll;
})(window);

代码示例

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="linkFlyScroll/linkFlyRollCss.css" rel="stylesheet" type="text/css" />
    <script src="linkFlyScroll/linkFlyScroll-1.0.0.js" type="text/javascript"></script>
    <script type="text/javascript">
        window.onload = function () {
            var config = {
                auto: true, //当内容并未达到容器的高度的时候,是否自动隐藏滚动条
                height: '100', //滚动条对象工作高度(超过该高度则显示滚动条),auto取对象当前高
                width: 'auto'//滚动条对象工作宽度
            };
            var scrollObj = so.scroll('obj', config);
            //            scrollObj.change();//当滚动条内容改变后,需要刷新滚动条的显示,则调用本方法
            //            scrollObj.roll(value);//把滚动条定位到某一点上,value为相对于滚动条对象的百分比
        };
    </script>
</head>
<body>
    <div id="obj">
        <div>
            当前,企业管理领域刮起一股新的“时尚风”,一些巨头企业纷纷为自己“瘦身”,向更智慧和灵动的业务转型。据了解,甲骨文软件正越来越多地把客户的主要维护成本向咨询顾问和第三方供应商转移。
            “在中国本土,90%的甲骨文公司业务是通过这些合作伙伴开展的。此外,为了进一步确保甲骨文的收入,CEO埃里森还购买了夏威夷的一个小岛。” Craig Guarente说道。
            作为全球副总裁,Guarente非常清楚甲骨文的各项战略。Guarente具有16年的工作经历,曾在合同管理、软件许可证管理、软件审计方面有丰富经验。2011年离开甲骨文后,加入了Palisade公司,该公司的主要业务是帮助甲骨文客户提供软件承包、审计介入和许可证“优化”等业务。
            Guarente表示,Palisade公司业务发展非常迅速。作为第三方机构,Palisade帮助客户赢得了大笔订单,因为他们更贴近市场,能更准确地理解用户需求。
            一般来说,咨询公司是帮助客户梳理他的实际需求及软件本身能提供什么价值。Guarente通过实际操作做了详细阐述。比如“你想建设一个新的数据中心,想要推出一个新的灾难恢复计划,或者你想进入云端,第三方公司首先会制定一个规划图,最后落实,达成用户最终目标。如果把软件部署在很多服务器的不同位置上,企业会有丢失软件的现象。因为企业软件很少能得到许可证密钥。但Oracle已经形成习惯,每一个可能功能都可以在软件环境下下载。Oracle数据库管理员通过自动负载的存储库(AWR)报告就可以诊断数据库问题,这是常见的事,但需要你有一个Oracle数据库包的许可。”
            近年来,随着软件审计浪潮的兴起,许多公司正在安装软件资产管理工具来确定他们使用什么软件,能使用多长时间,一个企业多少人在用。但资深管理分析师Hegedus说到:“没有任何工具能准确理解企业规则,尤其是甲骨文的产品应用,需要专业的第三方机构来帮助用户理解软件规则。”
            那么怎么才能为甲骨文的软件应用打补丁呢?甲骨文总裁马克•赫德(Mark Hurd)上周表示:在企业应用之初要把第三方机构定义为服务支持方,这样方便企业日后免费获得补丁修复和其他支持,而不只是购买产品知识产权。另外,企业要有效利用咨询顾问,在了解企业使用什么软件,协议应该包含什么内容时,支持成本控制的第一步。不要盲目离开软件供应商,按照自己预测和猜想的流程采购软件。
        </div>
    </div>
</body>
</html>

以上就是本文的全部内容了,讲解的十分详细,希望大家能够喜欢。


代码注释

作者:喵哥笔记

IDC笔记

学的不仅是技术,更是梦想!