首页 技术 正文
技术 2022年11月19日
0 收藏 555 点赞 2,918 浏览 17010 个字

话不多说,直接上源代码

一、tool.js

封装一些共用方法,以及相关的浏览器兼容细节,供Base.js调用

//浏览器检测,一旦加载即执行(function() {    window.sys = {};    var ua = navigator.userAgent.toLowerCase();    var s;    (s = ua.match(/msie ([\d.]+)/)) ? sys.ie = s[]:        (s = ua.match(/firefox\/([\d.]+)/)) ? sys.firefox = s[] :        (s = ua.match(/chrome\/([\d.]+)/)) ? sys.chrome = s[] :        (s = ua.match(/opera\/.*version\/([\d.]+)/)) ? sys.opera = s[] :        (s = ua.match(/version\/([\d.]+).*safari/)) ? sys.safari = s[] : ;    ];})();//取代window.onLoad的页面初始化加载函数function addDomLoaded(fn) {    var timer;    var isReady = false;    function doReady() {        if (timer) {            clearInterval(timer);        }        //isReady限制该方法仅执行一次        if (isReady) return;        isReady = true;        fn();    }    if (document.addEventListener) { //如果支持W3C,包括IE9+,chrome等        addEvent(document, 'DOMContentLoaded', function() {            fn();            removeEvent(document, 'DOMContentLoaded', arguments.callee);        });    } ) || (sys.firefox && sys.firefox < ) || (sys.webkit && sys.webkit < )) {        //下面两种方法都可以,不过这些低版本的浏览器市面上基本没有了,所以基本用不到        /*timer = setInterval(function () {            if (/loaded|complete/.test(document.readyState)) {  //loaded是部分加载,有可能只是DOM加载完毕,complete是完全加载,类似于onload                doReady();            }        }, 1);*/        timer = setInterval(function() {            if (document && document.getElementById && document.getElementsByTagName && document.body) {                doReady();            }        }, );    } ) {        //对于ie来说,检测readyState的方法,在页面具有iframe的时候失效,通过检测元素的scroll事件来实现        timer = setInterval(function() {            try {                document.documentElement.doScroll('left');                doReady();            } catch (e) {};        }, );    }}function hasClass(elem, className) {    return (new RegExp('(\\s+|^)' + className + '(\\s+|$)')).test(elem.className);}//获取元素的样式,可以是内联样式,也可以是写在外部样式表中的样式function getStyle(elem, attr) {    if (typeof window.getComputedStyle != 'undefined') { //W3C        return window.getComputedStyle(elem, null) [attr];    } else if (typeof elem.currentStyle != 'undefined') { //IE        return elem.currentStyle[attr];    }}//跨浏览器添加link规则function insertRule(sheet, selectorText, cssText, position) {    if (typeof sheet.insertRule != 'undefined') { //W3C        sheet.insertRule(selectorText + '{' + cssText + '}', position);    } else if (typeof sheet.addRule != 'undefined') { //IE        sheet.addRule(selectorText, cssText, position);    }}//跨浏览器移除link规则function deleteRule(sheet, index) {    if (typeof sheet.deleteRule != 'undefined') { //W3C        sheet.deleteRule(index);    } else if (typeof sheet.removeRule != 'undefined') { //IE        sheet.removeRule(index);    }}//跨浏览器获取浏览器视图的宽度和高度function getViewSize() {    var clientWidth = window.innerWidth;    var clientHeight = window.innerHeight;    if (typeof clientWidth != 'number') {        if (document.compatMode == 'CSS1Compat') {            clientWidth = document.documentElement.clientWidth;            clientHeight = document.documentElement.clientHeight;        } else { //IE6混杂模式下            clientWidth = document.body.clientWidth;            clientHeight = document.body.clientHeight;        }    }    return {        width: clientWidth,        height: clientHeight    }}//跨浏览器事件绑定,原事件绑定程序//DOM0级事件绑定(onclick等),事件处理程序是在元素作用域,this引用的是当前元素;只能绑定一个处理函数//DOM2级addEventListener(),元素作用域,可绑定多个,顺序执行//DOM2级IE attacheEvent(),全局window作用域,其中的event也属于window的属性,可绑定多个,逆序执行(貌似这个函数有内存泄漏的问题?)//综上,跨浏览器事件绑定程序,需要解决的问题包括//1,支持同一元素的同一事件可以绑定多个处理函数//2,如果同一元素的同一事件多次注册同一个处理函数,则仅生效一次//3,函数体内的this指定的是当前正在处理事件的节点//4,监听函数的执行顺序应当是按照注册绑定的顺序执行//5,在函数体内,不在使用event=event||window.event,来标准化event对象function addEvent(elem, type, listener) {    //type = type.replace(/^on/i, '').toLowerCase();    //将处理函数的作用域限制在元素内部,并将event对象传递过去    if (elem.addEventListener) {        elem.addEventListener(type, listener, false);    } else {        //为了避开attachEvent的内存泄漏问题,采用传统的事件绑定        if (!elem.events) {            //创建事件类型的哈希表            elem.events = {};        }        if (!elem.events[type]) {            elem.events[type] = [];        }        //判断同一个函数的事件是否已经被注册        if (!addEvent.contain(listener, elem.events[type])) {            elem.events[type].push(listener);        }        //真实绑定        elem['on' + type] = addEvent.exec;    }}//判断事件处理函数是否已经被注册addEvent.contain = function(listener, listenerArr) {    for (var i in listenerArr) {        if (listenerArr[i] == listener) {            return true;        }    }    return false;};//IE下最终绑定的事件处理函数addEvent.exec = function(event) {    //这里的this就是绑定事件的elem了    var e = event || addEvent.fixEvent(window.event);    var fns = this.events[e.type];    ; i < fns.length; i++) {        fns[i].call(this, e);    }};addEvent.fixEvent = function(event) {    event.target = event.srcElement;    event.preventDefault = addEvent.fixEvent.preventDefault;    event.stopPropagation = addEvent.fixEvent.stopPropagation;    return event;};addEvent.fixEvent.preventDefault = function() {    this.returnValue = false;};addEvent.fixEvent.stopPropagation = function() {    this.cancelBubble = true;};//跨浏览器删除事件function removeEvent(elem, type, listener) {    if (elem.removeEventListener) {        elem.removeEventListener(type, listener, false);    } else {        var fns = elem.events[type];        ; i < fns.length; i++) {            if (fns[i] == listener) {                fns.splice(i, );            }        }    }}//获得元素在页面上的水平偏移量function getElementLeft(elem) {    var pNode = elem.offsetParent;    var left = elem.offsetLeft;    while (pNode) {        left += pNode.offsetLeft;        pNode = pNode.offsetParent;    }    return left;}//获得元素在页面上的竖直偏移量function getElementTop(elem) {    var pNode = elem.offsetParent;    var top = elem.offsetTop;    while (pNode) {        top += pNode.offsetTop;        pNode = pNode.offsetParent;    }    return top;}function getScroll(){    return{        top:document.documentElement.scrollTop||document.body.scrollTop,        left:document.documentElement.scrollLeft||document.body.scrollLeft    }}//去除字符串开始和结束的空格function trim(str) {    str = str.replace(/(^\s*)|(\s*$)/g, '');    return str;}//和dom查找相关var query = function(selectorText, pNode) {    var regExps = {        id: /^#([\w_\-]+)/,        className: /^\.([\w_\-]+)/,        tag: /^\w+$/,        attribute: /(\w+)?\[([^=\]]+)(?:=(["'])?([^\]"']+)\3?)?\]/    };    var queryActions = {        id: function(id, pNode) {            var result = [];            result.push(document.getElementById(id));            return result;        },        tag: function(tag, pNode) {            var curPNode = null;            var result = [];            if (pNode != undefined) {                curPNode = pNode;            } else {                curPNode = document;            }            return curPNode.getElementsByTagName(tag);        },        className: function(className, parentNode) {            var pNode = null;            if (parentNode != undefined) {                pNode = parentNode;            } else {                pNode = document;            }            var result = [];            var elems = pNode.getElementsByTagName('*');            ; i < elems.length; i++) {                if (hasClass(elems[i], className)) {                    result.push(elems[i]);                }            }            return result;        },        attribute: function(tag, key, value, pNode) {            var curPNode = null;            if (pNode) {                curPNode = pNode;            } else {                curPNode = document;            }            var elems = curPNode.getElementsByTagName(tag || '*');            var result = [];            ; i >= ; i--) {                var curElem = elems[i];                if (curElem.getAttribute(key)) {                    if (!value) {                        result.push(curElem);                    } else {                        if (curElem.getAttribute(key).toLowerCase() === value.toLowerCase()) {                            result.push(curElem);                        }                    }                }            }            return result;        }    };    var fnName, regResult;    var params = [];    if (regResult = selectorText.match(regExps['id'])) {        fnName = 'id';        ]);    }    if (regResult = selectorText.match(regExps['tag'])) {        fnName = 'tag',            ]);    }    if (regResult = selectorText.match(regExps['className'])) {        fnName = 'className',            ]);    }    if (regResult = selectorText.match(regExps['attribute'])) {        fnName = 'attribute',            ], regResult[], regResult[]);    }    if (pNode) {        params.push(pNode);    }    var elemResult = queryActions[fnName].apply(null, params);    return elemResult;};

tool.js

二、Base.js 调用tool.js,效果类似于一个轻量级的jquery

//前台调用function $(args) {    return new Base(args);}function Base(args) {    this.elements = [];    if (typeof args === 'string') {        //说明是css选择符        args = trim(args);        var selectors = [];        ) {            selectors = args.split(/\s+/);        } else {            //说明选择符不具有层次关系,为了方便处理,依旧将其转换为数组            selectors.push(args);        }        var pNodes = [];        var childNodes = [];        ; i < selectors.length; i++) {            var curSelector = selectors[i];            ) {                pNodes.push(document);            }            childNodes = [];            ; j < pNodes.length; j++) {                var temps = query(curSelector, pNodes[j]);                ; k < temps.length; k++) {                    childNodes.push(temps[k]);                }            }            pNodes = childNodes;        }        this.elements = childNodes;    } else if (typeof args === 'object') {        //说明传入的是dom对象,或者this        if (args != undefined) {            ] = args;        }    } else if (typeof args === 'function') {        this.ready(args);    }}//页面加载函数,类似于jquery的$(document).readyBase.prototype.ready = function(fn) {    addDomLoaded(fn);};//获取某一个节点,返回的是DOM节点对象Base.prototype.getElem = function(num) {    return this.elements[num];};//返回符合条件的首个DOM节点对象Base.prototype.first = function() {    ];};//返回符合条件的最后一个DOM节点对象Base.prototype.last = function() {    ];};//返回当前节点的上一个同级节点,返回的是Base对象Base.prototype.next = function() {    ; i < this.elements.length; i++) {        this.elements[i] = this.elements[i].nextSibling;        if (this.elements[i] == null) {            throw new Error('找不到下一个同级节点!');        }        ) {            this.next();        }    }    return this;};Base.prototype.prev = function() {    ; i < this.elements.length; i++) {        this.elements[i] = this.elements[i].previousSibling;        if (this.elements[i] == null) {            throw new Error('找不到上一个同级节点!');        }        ) {            this.prev();        }    }    return this;};//获取某一个节点,返回的是Base对象Base.prototype.eq = function(num) {    var element = this.elements[num];    this.elements = [];    ] = element;    return this;};Base.prototype.css = function(attr, value) {    , len = this.elements.length; i < len; i++) {        ) {            return getStyle(this.elements[i], attr);        }        this.elements[i].style[attr] = value;    }    return this;};//获取长度Base.prototype.len = function() {    return this.elements.length;};Base.prototype.addClass = function(className) {    , len = this.elements.length; i < len; i++) {        if (!hasClass(this.elements[i], className)) {            this.elements[i].className += ' ' + className;        }    }    return this;};Base.prototype.removeClass = function(className) {    , len = this.elements.length; i < len; i++) {        if (hasClass(this.elements[i], className)) {            this.elements[i].className = this.elements[i].className.replace(new RegExp('(\\s+|^)' + className + '(\\s+|$)'), ' ');        }    }    return this;};//获取或者设置innerHTML//潜在问题,如果是赋值的话,所有都赋值,如果是取值的话,貌似只是返回首个值Base.prototype.html = function(htmlText) {    , len = this.elements.length; i < len; i++) {        ) {            return this.elements[i].innerHTML;        } else {            this.elements[i].innerHTML = htmlText;        }    }    return this;};//添加link或者style的css规则,不常用Base.prototype.addRule = function(num, selectorText, cssText, position) {    var sheet = document.styleSheets[num];    insertRule(sheet, selectorText, cssText, position);    return this;};//删除link或者style的css规则,不常用Base.prototype.removeRule = function(num, index) {    var sheet = document.styleSheets[num];    deleteRule(sheet, index);    return this;};//设置元素显示Base.prototype.show = function() {    ; i >= ; i--) {        this.elements[i].style.display = 'block';    };    return this;};//设置元素隐藏Base.prototype.hide = function() {    ; i >= ; i--) {        this.elements[i].style.display = 'none';    };    return this;};//检查元素是否处于隐藏状态Base.prototype.isVisible = function() {    var flag=true;    ; i >= ; i--) {        var curElem=this.elements[i];        if(curElem.style.display=='none'||curElem.style.visibility=='hidden'){            flag=false;        }    };    return flag;};//设置已知宽度和高度的物体,在整个视图窗口居中//前提:当前元素position:absolute,父元素是body对象Base.prototype.screenCenter = function(width, height) {    var viewSize = getViewSize();    var left, top;    , len = this.elements.length; i < len; i++) {        var curElem = this.elements[i];        ) {            left = (viewSize.width - width) / ;            top = (viewSize.height - height) / ;        } else {            //没有传入元素的宽和高,就自己获取            left = (viewSize.width - curElem.offsetWidth) / ;            top = (viewSize.height - curElem.offsetHeight) / ;        }        this.elements[i].style.top = top + 'px';        this.elements[i].style.left = left + 'px';    };    return this;};//浏览器大小调整事件,可以用任意$()对象调用Base.prototype.resize = function(fn) {    addEvent(window, 'resize', fn);    //window.onresize = fn;    return this;};//设置hover事件Base.prototype.hover = function(over, out) {    , len = this.elements.length; i < len; i++) {        //this.elements[i].onmouseover = over;        addEvent(this.elements[i], 'mouseover', over);        //this.elements[i].onmouseout = out;        addEvent(this.elements[i], 'mouseout', out);    };    return this;};//toggle:点击切换方法,可以传递多个函数作为参数,执行完一轮则从头开始执行Base.prototype.toggle = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        var args = arguments;        //最终方法,这样的话每一个元素都具有单独的一个count计数器,并且不会产生诸如curElem.count这样的属性污染        (function(curElem, args) {            ;            addEvent(curElem, 'click', function() {                args[count++ % args.length].call(this);            });        })(curElem, args);        //方法二:可以解决方法一的问题,但是依旧不行,因为如果选择器选择的是多个元素的话,公用一个count对象,可能会出现问题        // addEvent(curElem, 'click', function() {        //     //注意,在函数内定义函数,这是一个闭包        //     //闭包可以访问外部函数的变量,但是保存的永远是外部函数变量的最后取值        //     //因此这里count的取值才能始终累加        //     //不是增添多次click事件,并且每次click事件的执行函数事实上都不相同        //     args[count++ % args.length].call(this);        // });        //方法一:这种方式是不行的,执行的永远是第一个函数        //addEvent(curElem,'click',args[count++%args.length]);    }    return this;};function tog(curElem, args) {    ;    addEvent(curElem, 'click', function() {        args[count++ % args.length].call(this);    });}//添加点击事件Base.prototype.click = function(fn) {    ; i < this.elements.length; i++) {        addEvent(this.elements[i], 'click', fn);    }    return this;};//插件入口Base.prototype.extend = function(name, fn) {    Base.prototype[name] = fn;};Base.prototype.find = function(selector) {    var pNodes = this.elements;    this.elements = [];    ; i < pNodes.length; i++) {        var tmps = query(selector, pNodes[i]);        ; j < tmps.length; j++) {            this.elements.push(tmps[j]);        }    }    return this;};//调用方法$().animate(styles,speed,callback,easing);//styles:必选,如{width:100px}目前支持,top,left,width,height,opacity//speed 可选,默认动画的速度,每多长时间执行一次,默认为30ms//step 每一次动画执行步长,默认为10像素//callback:动画执行之后的回调//easing:动画速度的缓动函数,默认匀速Base.prototype.animate = function(styles, callback, speed, step, easing) {    function setValue(curElem, attr, nowValue) {        curElem.style[attr] = (attr == ) : nowValue + 'px');        if (attr == 'opacity') {            curElem.style.filter = 'opacity(alpha=' + nowValue + ')';        }        document.getElementById('content').innerHTML += attr + ':' + getStyle(curElem, attr) + '</br>';    }    var finalValue, startValue, nowValue;    ;    ;    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        if (curElem.timer) {            clearInterval(curElem.timer);        }        var temp = [];        for (var attr in styles) {            //每一组都有startValue,finalValue            startValue = (attr ==  : parseInt(getStyle(curElem, attr)));            finalValue = (attr ==  : parseInt(styles[attr]));            step = (startValue < finalValue ? step : -step);            temp.push([attr, startValue, step, finalValue]);            //将各项值都复原,第二次动画的时候貌似不能复原了。。。            setValue(curElem, attr, startValue);        }        curElem.timer = setInterval(function() {            var flag = true; //判断是否所有的动画都已经结束,除了初始化的这次,如果为true,代表所有动画都结束            ; i < temp.length; i++) {                attr = temp[i][];                nowValue = temp[i][];                step = temp[i][];                finalValue = temp[i][];                 && finalValue <= nowValue + step) || (step <  && finalValue >= nowValue + step)) {                    //应当所有的动画都执行完毕,才能清除掉计时器                    //   clearInterval(curElem.timer);                    nowValue = finalValue;                    setValue(curElem, attr, finalValue);                } else {                    nowValue += step;                    setValue(curElem, attr, nowValue);                }                temp[i][] = nowValue;                if (nowValue != finalValue) {                    flag = false;                }            };            if (flag) {                clearInterval(curElem.timer);                if (callback) {                    callback.call(curElem);                }            }        }, speed);    };    return this;};Base.prototype.fadeIn = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        $(curElem).animate({        });    };    return this;};Base.prototype.fadeOut = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        $(curElem).animate({        });    };    return this;};Base.prototype.slideUp = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        if (getStyle(curElem, 'display') != 'none') {            var startHeight = getStyle(curElem, 'height');            $(curElem).animate({            }, function() {                $(this).hide().css('height', startHeight);                //console.log(getStyle(this,'height'));            });        }    };    return this;};Base.prototype.slideDown = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        //console.log(getStyle(curElem,'display'));        if (getStyle(curElem, 'display') == 'none') {            var startHeight = getStyle(curElem, 'height');            $(curElem).css('height', '0px').show().animate({                'height': startHeight            });        }    };    return this;};//设置绑定事件方法Base.prototype.bind = function(type, fn) {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        addEvent(curElem, type, fn);    };    return this;};//设置focus事件Base.prototype.focus = function(fn) {    this.bind('focus', fn);};//设置blur事件Base.prototype.blur = function(fn) {    this.bind('blur', fn);};//获得或者设置表单元素的valueBase.prototype.val = function(curValue) {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        if (curValue) {            curElem.value = curValue;        } else {            return curElem.value;        }    }    return this;};Base.prototype.attr = function(attr, value) {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        if (value == undefined) {            return curElem.getAttribute(attr);        } else {            curElem.setAttribute(attr, value);        }    }    return this;};//在之前插入元素Base.prototype.insertBefore = function(elem) {    , len = this.elements.length; i < len; i++) {        var curElem = this.elements[i];        var pNode = elem.parentNode;        pNode.insertBefore(curElem, elem);    }    return this;};Base.prototype.insertAfter = function(elem) {    , len = this.elements.length; i < len; i++) {        var curElem = this.elements[i];        var pNode = elem.parentNode;        if (pNode.lastChild === elem) {            pNode.appendChild(curElem);        } else {            pNode.insertBefore(curElem, elem.nextSibling);        }    }    return this;};//获取元素的高度Base.prototype.top = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        return getElementTop(curElem);    };};Base.prototype.left = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        return getElementLeft(curElem);    };};Base.prototype.width = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        return curElem.offsetWidth;    };};Base.prototype.height = function() {    ; i < this.elements.length; i++) {        var curElem = this.elements[i];        return curElem.offsetHeight;    };};

base.js

三、Base_drag.js基于Base.js的拖拽插件

//将拖拽封装为库$().extend('drag', function() {    var tags=arguments;    for (var i = 0; i < this.elements.length; i++) {        var curElem = this.elements[i];         addEvent(curElem, 'mousedown', function(e) {             var diffX = e.clientX - getElementLeft(this);             var diffY = e.clientY - getElementTop(this);             var that = this;             //限定只有点击部分区域才可以拖动             var flag = false;             for (var j = 0; j < tags.length; j++) {                 if (e.target.tagName.toLowerCase() == tags[j].toLowerCase()) {                     flag = true;                     break;                 }             }             function move(e) {                 var left = e.clientX - diffX;                 var top = e.clientY - diffY;                 //如果超出了当前视图边缘则禁止脱宅                 if (left < 0) {                     left = 0;                 }                 if (top < 0) {                     top = 0;                 }                 var viewSize = getViewSize();                 if (left > viewSize.width - that.offsetWidth) {                     left = viewSize.width - that.offsetWidth;                 }                 if (top > viewSize.height - that.offsetHeight) {                     top = viewSize.height - that.offsetHeight;                 }                 that.style.left = left + 'px';                 that.style.top = top + 'px';             }             function up(e) {                 removeEvent(document, 'mousemove', move);                 removeEvent(document, 'mouseup', up);             }             if (flag) {                 addEvent(document, 'mousemove', move);                 addEvent(document, 'mouseup', up);             }         });    }});

Base_drag.js

四、Base_screenlock.js 基于Base.js的锁屏插件

//javascript锁屏插件$().extend('lock', function() {    var viewSize = getViewSize();    for (var i = this.elements.length - 1; i >= 0; i--) {        var curElem = this.elements[i];        curElem.style.width = viewSize.width + 'px';        curElem.style.height = viewSize.height + 'px';        curElem.style.display = 'block';    };    document.documentElement.style.overflow = 'hidden';    return this;});$().extend('unlock', function() {    for (var i = 0; i < this.elements.length; i++) {        this.elements[i].style.display = 'none';    };    document.documentElement.style.overflow = 'auto';    return this;});

Base_screenlock.js

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,580
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918