zoukankan      html  css  js  c++  java
  • 我要学习之墨鱼JQ

    /**
     * moyuQuery的大部分API方法名和jQuery保持一致,可以结合jQuery的文档来阅读本库
     * www.moyu-edu.com
     * 
     */
    
    //立即函数自执行
    //把window传进来,可以不用每次访问都去全局作用域,提高代码执行速度
    //因为在有的低版本IE中undefined的值有可能改写,所以传进来,但是调用的时候实参没有这个,所以保证是正确的undefined
    ;(function(window,undefined){
        //代码9到96行的作用在于选择出来了我们要的一组DOM对象,并存到我们的moyuQuery对象中作为一个属性名为arr的数组中
        //moyuQuery构造器
        function moyuQuery(str){
            //防止非法访问
            if(this === window){
                return new moyuQuery(str);
            }
    
            //Sizzle解析引擎,模拟jQuery的sizzle
            function Sizzle(str){
                var str = str.toLowerCase();
                //如果是类似$("#abc")这样的形式,直接返回,提高性能
                var quickMatchIdReg = /^#[a-z]+$/;
                if(quickMatchIdReg.test(str)){
                    return [document.getElementById(str)];
                }
    
                var list = str.split(" ");
                var eleArr = [];
                var tempArr = [];
    
                for(var i=0;i<list.length;i++){
                    if(eleArr.length === 0){
                        eleArr = manipuEasyDom(list[i],document);
                    }else{
                        tempArr = [];//每次进来执行的时候置空tempArr
                        for(var j=0;j<eleArr.length;j++){
                            tempArr = tempArr.concat(manipuEasyDom(list[i],eleArr[j]));
                        }
                        eleArr = tempArr;
                    }
                    
                }
                // 只考虑了最简单的三种情况选择器 id,class,标签
                function manipuEasyDom(str,fatherDom){
                    var reg1 = /^#(w+)/;//匹配id
                    var reg2 = /^.(w+)/;//匹配class
                    var reg3 = /^w+/;//匹配标签
    
                    var myArr = [];
                    //str代表的是传进来的参数 "#abc" ".abc" "abc"
                    if(reg1.test(str) === true){
                        var arr = reg1.exec(str);
                        //console.log(arr);
                        var oDiv = fatherDom.getElementById(arr[1]);
                        myArr.push(oDiv);
                    }
    
                    if(reg2.test(str) === true){
                        var arr = reg2.exec(str);
                        var aList = fatherDom.getElementsByClassName(arr[1]);
                        myArr = Array.prototype.slice.call(aList,0);
                    }
    
                    if(reg3.test(str) === true){
                        var aList = fatherDom.getElementsByTagName(str);
                        myArr = Array.prototype.slice.call(aList,0);
                    }
                    return myArr;
                }
                return eleArr;
            }
    
            //判断是 $(function(){})、$("#demo") 还是其他的调用类型
            switch(typeof str){
                case "function"://如果是$(function(){})这种方式,那就是简写的ready形式    
                    moyuQuery.ready(str);
                    break;
                case "string"://只考虑像 $("#a div") $(".a div") $("div .item") $("div") $(".item") $("#a")这些形式,不考虑伪类、CSS3选择器
                    this.arr = Sizzle(str);
                    break;
                case "object":
                    //说明是用getElementsByTagName,getElementsByClassName选择出来的
                    if(str.toString().indexOf("Element") > -1){
                        this.arr = [str];
    
                    //说明是用getElementsByTagName,getElementsByClassName选择出来的    
                    }else if(str.toString().indexOf("Collection") > -1){
                        this.arr = str;
                    //出错了    
                    }else{
                        return {};
                    }
                    break;
                default:
                    //出错了    
                    return {};
                    break;    
            }
        }
    
    
    
        //eq就是等于的意思
        //eq(0) --> 把arr数组的第1个拿出来
        moyuQuery.prototype.eq = function(num){
            return new moyuQuery(this.arr[num]);
        }
    
        //获取第一个元素DOM对象并转换成moyuQuery对象
        moyuQuery.prototype.first = function(){
            return new moyuQuery(this.arr[0]);
        }
    
        //获取最后一个元素DOM对象并转换成moyuQuery对象
        moyuQuery.prototype.last = function(){
            return new moyuQuery(this.arr[this.arr.length - 1]);
        }
    
    
    
        //求整个moyuQuery对象中的DOM元素的个数
        moyuQuery.prototype.length = function(){
            return this.arr.length;
        }
        //求整个moyuQuery对象中的DOM元素的个数
        moyuQuery.prototype.size = moyuQuery.prototype.length;
    
    
        //+++++++++++++++++++++++++++++事件模块开始+++++++++++++++++++++++++++++++++++++++++++
        //on相当于给this.arr里所有的元素对象加事件
        moyuQuery.prototype.on = function(eventType,fn){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].addEventListener(eventType,fn,false);
            }
            return this;
        }
    
        //给一些常见的事情设置一些快捷方式,比如click可以直接 $("div").click(function(){})这样用
        var eventList = 'click mouseover mouseout mousedown mousemove mouseup keydown keyup dblclick contextmenu input propertychange change blur focus resize scroll load'.split(" ");
        for(var i=0;i<eventList.length;i++){
            //这里用到了闭包的技巧
            moyuQuery.prototype[eventList[i]] = (function(eventType){
                var eventFn = function(fn){
                    this.on(eventType,fn);
                }
                return eventFn;
            })(eventList[i]);
        }    
    
        //ele.removeEventListener("click",fnName);
        //off相当于给this.arr里面所有的元素对象移除事件
        moyuQuery.prototype.off = function(eventType,fn){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].removeEventListener(eventType,fn);
            }
            return this;
        }
    
        //类似css中的hover伪类
        moyuQuery.prototype.hover = function(fn1,fn2){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].addEventListener("mouseenter",fn1,false);
                this.arr[i].addEventListener("mouseleave",fn2,false);
            }
        }
    
        //++++++++++++++++++++++++++++++++事件模块结束++++++++++++++++++++++++++++++++++++++++
    
    
        //++++++++++++++++++++++++++++++++DOM模块开始++++++++++++++++++++++++++++++++++++++++
        //show给this.arr里所有的元素让它显示出来
        moyuQuery.prototype.show = function(){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].style.display = "block";
            }
            return this;
        }
    
        //hide给this.arr里所有的元素让它隐藏出来
        moyuQuery.prototype.hide = function(){
            console.log(this.arr);
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].style.display = "none";
            }
            return this;
        }
    
        //如果显示,就隐藏,否则显示
        moyuQuery.prototype.toggle = function(){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].addEventListener("click",function(){
                    if(getStyle(this).display === "block"){
                        this.style.display = "none";
                    }else{
                        this.style.display = "block";
                    }
                },false);
            }
        }
    
        //获取计算后样式
        function getStyle(ele){
            if(window.getComputedStyle){
                return getComputedStyle(ele);
            }else{
                return ele.currentStyle;
            }
        }
    
        //如果传进来一个参数是获取,否则是设置
        moyuQuery.prototype.css = function(styleName,styleValue){
            if(styleValue === undefined){
                return getStyle(this.arr[0])[styleName];
            }else{
                for(var i=0;i<this.arr.length;i++){
                    this.arr[i].style[styleName] = styleValue;
                }
            }        
        }
    
        //如果传进来一个参数是获取,否则是设置
        moyuQuery.prototype.attr = function(attrName,attrValue){
            if(attrValue === undefined){
                return this.arr[0].getAttribute(attrName);
            }else{
                for(var i=0;i<this.arr.length;i++){
                    this.arr[i].setAttribute(attrName,attrValue);
                }
            }
        }
    
        //如果传进来一个参数是获取,否则是设置
        moyuQuery.prototype.val = function(valName,valValue){
            if(valName === undefined){
                return this.arr[0][valName];
            }else{
                for(var i=0;i<this.arr.length;i++){
                    this.arr[i][valName] = valValue;
                }
            }
        }
    
    
        // 给this.arr里所有的元素加一个className "abc def"
        moyuQuery.prototype.addClass = function(str){
            for(var i=0;i<this.arr.length;i++){
                //"abc" "abc def"
                this.arr[i].className += " " + str;
            }
        }
    
        //移出类名
        moyuQuery.prototype.removeClass = function(str){
            for(var i=0;i<this.arr.length;i++){
                //"abc def abc"
                var reg = new RegExp("\b" + str + "\b","g");
                this.arr[i].className = this.arr[i].className.replace(reg,"");
                // this.arr[i].className += " " + str;
            }
        }
    
        //如果存在(不存在)就删除(添加)一个类。
        //原型 
        moyuQuery.prototype.toggleClass = function(str){
            for(var i=0;i<this.arr.length;i++){
                var reg = new RegExp("\b" + str + "\b","g");
                "abc def"
                if(reg.test(this.arr[i].className) === true){
                    this.arr[i].className = this.arr[i].className.replace(reg,"");
                }else{
                    this.arr[i].className += " " + str;
                }
            }
        }
        // myObj.html("abc");
        moyuQuery.prototype.html = function(str){
            if(str === undefined){
                return this.arr[0].innerHTML;
            }
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].innerHTML = str;
            }
        }
    
        //参考innerText的功能
        moyuQuery.prototype.text = function(str){
            if(str === undefined){
                return this.arr[0].innerText;
            }
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].innerHTML = str;
            }
        }
    
        //清空moyuQuery中的DOM对象的innerHTML
        moyuQuery.prototype.empty = function(){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].innerHTML = "";
            }
        }
    
        //删除moyuQuery中的DOM对象
        moyuQuery.prototype.remove = function(){
            for(var i=0;i<this.arr.length;i++){
                this.arr[i].parentNode.removeChild(this.arr[i]);
            }
        }
    
        //获取和设置
        moyuQuery.prototype.width = function(widthValue){
            if(widthValue === undefined){
                return getStyle(this.arr[0]).width;
            }else{
                for(var i=0;i<this.arr.length;i++){
                    this.arr[i].style.width = widthValue + "px";
                }
            }
        }
    
        //获取和设置
        moyuQuery.prototype.height = function(heightValue){
            if(heightValue === undefined){
                return getStyle(this.arr[0]).height;
            }else{
                for(var i=0;i<this.arr.length;i++){
                    this.arr[i].style.height = heightValue + "px";
                }
            }
        }
    
        moyuQuery.prototype.innerWidth = function(){
            var styleObj = getStyle(this.arr[0]);
            return parseInt(styleObj["width"]) + parseInt(styleObj["paddingLeft"]) + parseInt(styleObj["paddingRight"]);
        }
    
        moyuQuery.prototype.innerHeight = function(){
            var styleObj = getStyle(this.arr[0]);
            return parseInt(styleObj["height"]) + parseInt(styleObj["paddingTop"]) + parseInt(styleObj["paddingBottom"]);
        }
    
        moyuQuery.prototype.outerWidth = function(check){
            var styleObj = getStyle(this.arr[0]);
            if(check === true){
                return parseInt(styleObj["width"]) + parseInt(styleObj["paddingLeft"]) + parseInt(styleObj["paddingRight"]) + parseInt(styleObj["borderLeftWidth"]) + parseInt(styleObj["borderRightWidth"]) + parseInt(styleObj["marginLeft"]) + parseInt(styleObj["marginRight"]);
            }else{
                return parseInt(styleObj["width"]) + parseInt(styleObj["paddingLeft"]) + parseInt(styleObj["paddingRight"]) + parseInt(styleObj["borderLeftWidth"]) + parseInt(styleObj["borderRightWidth"]);
            }
        }
    
        moyuQuery.prototype.outerHeight = function(){
            var styleObj = getStyle(this.arr[0]);
            if(check === true){
                return parseInt(styleObj["height"]) + parseInt(styleObj["paddingTop"]) + parseInt(styleObj["paddingBottom"]) + parseInt(styleObj["borderTopWidth"]) + parseInt(styleObj["borderBottomWidth"]) + parseInt(styleObj["marginTop"]) + parseInt(styleObj["marginBottom"]);
            }else{
                return parseInt(styleObj["height"]) + parseInt(styleObj["paddingTop"]) + parseInt(styleObj["paddingBottom"]) + parseInt(styleObj["borderTopWidth"]) + parseInt(styleObj["borderBottomWidth"]);
            }
        }
    
        //获取当前元素与CSS定位上的父级的偏移量    
        moyuQuery.prototype.offset = function(){
            return {
                left:this.arr[0].offsetLeft,
                top:this.arr[0].offsetTop
            };
        }
    
    
        function getPos(ele){
            var posObj = {
                left:ele.offsetLeft + parent.clientLeft - parent.scrollLeft,
                top:ele.offsetTop + parent.clientTop- parent.scrollTop
            }
            var parent = ele.offsetParent;
            while(parent!=null){
                posObj.left += parent.offsetLeft + parent.clientLeft - parent.scrollLeft;
                posObj.top += parent.offsetTop + parent.clientTop- parent.scrollTop;
                parent = parent.offsetParent;
            }
            return posObj;
        }
    
        // 把moyuQuery中的DOM对象包一层父级
        moyuQuery.prototype.position = function(){
            return getPos(this.arr[0]);
        }
    
        moyuQuery.prototype.scrollLeft = function(){
            return this.arr[0].scrollLeft;
        }
    
        moyuQuery.prototype.scrollTop = function(){
            return this.arr[0].scrollTop;
        }
    
        //获取第1个DOM对象与视窗的偏移坐标
        moyuQuery.wrap = function(str){
            var fragment = document.createDocumentFragment();
            var oDiv = document.createElement("div");
            fragment.appendChild(oDiv);
            oDiv.innerHTML = str;
            var myEle = oDiv.children[0];
            for(var i=0;i<this.arr.length;i++){
                var myEle1 = myEle.cloneNode(true);
                this.arr[i].parentNode.insertBefore(myEle1,this.arr[i]);
                myEle1.appendChild(this.arr[i]);
            }
        }
    
        //把当前的DOM对象这一层去掉
        moyuQuery.prototype.unwrap = function(){
            for(var i=0;i<this.arr.length;i++){
                //找出来所有的当前DOM对象的子元素,先加到对应的位置,再把当前DOM对象删除掉
                var myChildren = this.arr[i].children;
                for(var j=0;j<myChildren.length;j++){
                    this.arr[i].parentNode.insertBefore(this.arr[i].children,this.arr[i]);
                }
                this.arr[i].parentNode.removeChild(this.arr[i]);
            }
        }
        //++++++++++++++++++++++++++++++++DOM模块结束++++++++++++++++++++++++++++++++++++++++
    
    
        //++++++++++++++++++++++++++++++++ajax&jsonp模块开始++++++++++++++++++++++++++++++++++++++++
    
        //jsonp方式获取数据
        moyuQuery.jsonp = function(link,fn){
            window.fn = fn;
            var oScript = document.createElement("script");
            oScript.src = link;
        }
    
    
        //args代表的是传的参数
        moyuQuery.get = function(link,args,fn){
            var xhr = null;
            if(window.XMLHttpRequest){
                xhr = new XMLHttpRequest();
            }else{
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
    
            xhr.open("GET",link+"?a="+(new Date()).getTime()+"&"+args);
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4 && xhr.status === 200){
                    if(typeof fn === "function"){
                        fn();
                    }
                }
            }
            xhr.send(null);
        }
    
        //ajax的POST方式提交数据
        moyuQuery.post = function(){
            var xhr = null;
            if(window.XMLHttpRequest){
                xhr = new XMLHttpRequest();
            }else{
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
    
            xhr.open("POST",link);
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4 && xhr.status === 200){
                    if(typeof fn === "function"){
                        fn();
                    }
                }
            }
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xhr.send(args);
        }
        //++++++++++++++++++++++++++++++++ajax&jsonp模块结束++++++++++++++++++++++++++++++++++++++++
    
    
        //缓存数据
        moyuQuery.prototype.data = function(valName,valValue){
            if(valValue === undefined){
                return this[valName];
            }else{
                this[valName] = valValue;
            }
        }
    
        //表单序列化
        moyuQuery.prototype.serialize = function(){
            var list = this.arr[0].getElementsByTagName('*');
            var tempStr = "";
            for(var i=0;i<list.length;i++){
                if(list[i].tagName.toLowerCase() === "input"){
                    if(list[i].getAttribute("type").search(/text|password|email|date|range|color|url/)){
                        tempStr += list[i].getAttribute("name") + "=" + list[i].value + "&";
                    }
                }
            }
            return tempStr.replace(/&$/,"");
        }
    
        //裁剪
        moyuQuery.prototype.slice = function(m,n){
            this.arr.slice(m,n);
            return this;
        }
        //插件化
        moyuQuery.prototype.extend = function(obj){
            for(var i in obj){
                this[i] = obj[i];
            }
        }
    
        //each
        //fn默认形参 index ele
        moyuQuery.prototype.each = function(fn){
            for(var i=0;i<this.arr.length;i++){
                fn.call(window,i,this.arr[i]);
            }
        }
    
    
    
    
        //当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。
        moyuQuery.ready = function(fn){
            if(document.addEventListener){
                document.addEventListener("DOMContentLoaded",function(){
                    if(typeof fn === "function"){
                        fn();
                    }
                },false);
            }else{
                document.onreadystatechange = function(evt){
                    evt = evt || event;
                    if(evt.readyState === "complete"){
                        if(typeof fn === "functioin"){
                            fn();
                        }
                    }
                }
            }
        }
    
        moyuQuery.each = function(arr,fn){
            for(var i=0;i<arr.length;i++){
                fn(i,arr[i]);
            }
        }
    
        //exObj对象的属性拷贝到srcObj身上
        moyuQuery.extend = function(srcObj,exObj){
            for(var i in exObj){
                srcObj[i] = exObj[i];
            }
        }
    
        //检测该字符串是否像数字
        moyuQuery.isNumeric = function(str){
            if(typeof str === "number"){
                return true;
            }
            var reg = /^d+$/;
            if(reg.test(str)){
                return true;
            }else{
                return false;
            }
        }
    
        //检测是否是数组类型数据
        moyuQuery.isArray = function(arr){
            if(Object.prototype.toString.call(arr).indexOf("Array") > -1){
                return true;
            }else{
                return false;
            }
        }
    
        moyuQuery.isPlainObject = function(obj){
            if(Object.prototype.toString.call(obj) === "[object Object]"){
                return true;
            }else{
                return false;
            }
        }
    
        moyuQuery.type = function(ele){
            switch(Object.prototype.toString.call(ele)){
                case "[object Array]":
                    return "array";
                    break;
                case "[object Date]":
                    return "date";
                    break;
                case "[object RegExp]":
                    return "regexp";
                    break;
                case "[object String]":
                    return "string";
                    break;
                case "[object Function]":
                    return "function";
                    break;
                case "[object Number]":
                    return "number";
                    break;
                case "[object Boolean]":
                    return "boolean";
                    break;
                case "[object Null]":
                    return "null";
                case "[object Undefined]":
                    return "undefined";
                    break;
            }
        }
    
        moyuQuery.merge = function(arr1,arr2){
            return arr1.concat(arr2);
        }
    
        //保证数组中没有元素相同,去重
        moyuQuery.unique = function(arr1){
            var arr = [];
            for(var i=0;i<arr1.length;i++){
                if(arr.indexOf(arr1[i]) === -1){
                    arr.push(arr[i]);
                }
            }
            return arr;
        }
    
        moyuQuery.makeArray = function(list){
            return Object.prototype.slice.call(list);
        }
    
        moyuQuery.inArray = function(item,arr){
            if(arr.indexOf(item) > -1){
                return true;
            }else{
                return false;
            }
        }
    
        //过滤函数
        moyuQuery.grep = function(arr,fn){
            var myArr = [];
            for(var i=0;i<arr.length;i++){
                if(fn(arr[i]) === true){
                    myArr.push(arr[i]);
                }
            }
            return myArr;
        }
    
        moyuQuery.noop = function(){}
    
        moyuQuery.trim = function(str){
            var reg = /^s+|s+$/g;
            return str.replace(reg,"");
        }
    
    
        moyuQuery.map = function(arr,fn){
            var newArr = [];
            for(var i=0;i<arr.length;i++){
                newArr.push(fn(arr[i]));
            }
            return newArr;
        }
    
        //把"background-color"转换成"backgroundColor"
        moyuQuery.camelCase = function(str){
            var reg = /-(w)/g;
            return str.replace(reg,function(a,b){
                return b.toUpperCase();
            });
        }
    
        //检查元素的
        moyuQuery.now = function(){
            return (new Date());
        }
    
        //防冲突
        moyuQuery._$ = window.$;
        moyuQuery.noConflict = function(){
            window.$ = moyuQuery._$;
        }
    
        moyuQuery.VERSION = "0.01";
    
        //var a = 1;
        //window.a = a;
        
        
        //暴露给全局只有moyuQuery和$对象
        window.moyuQuery  = moyuQuery;//设置了一个全局变量名字叫$,值是moyuQuery
        window.$ = moyuQuery
        
    }(window));
  • 相关阅读:
    了解 NoSQL 的必读资料
    关于什么时候用assert(断言)的思考
    这次见到了一些大侠
    NetBeans 时事通讯(刊号 # 87 Jan 12, 2010)
    动态链接库dll,静态链接库lib, 导入库lib
    新女性十得 写得了代码,查得出异常
    记录系统乱谈
    新女性十得 写得了代码,查得出异常
    fullpage.js禁止滚动
    RunningMapReduceExampleTFIDF hadoopclusternet This document describes how to run the TFIDF MapReduce example against ascii books. This project is for those who wants to experiment hadoop as a skunkworks in a small cluster (110 nodes) Google Pro
  • 原文地址:https://www.cnblogs.com/shanchenba/p/5567408.html
Copyright © 2011-2022 走看看