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));
  • 相关阅读:
    GROK解析正则表达式
    夜神模拟器和Hbuilder连接
    使用notepad++批量在每行首尾添加内容
    mybatis-plus
    laravel controller 层---数据库操作
    laravel controller 层---请求参数传递
    laravel controller 层---数据验证
    laravel model 层
    laravel 博客收藏,转载篇
    laravel 用法大全开始
  • 原文地址:https://www.cnblogs.com/shanchenba/p/5567408.html
Copyright © 2011-2022 走看看