模拟一个自己的jquery(四) 操作样式

操作样式相关方法

js操作样式最简单的就是获取元素的style属性以及修改style属性,设置样式可以设置style的值,但是获取样式使用style往往不能得到想要的值,因为style只能获取到直接设置在元素style上面的样式,而我们样式往往是在单独的css文件里面,所以获取样式不能使用style。

那么怎么获取正确的元素样式呢,我们可以通过document.defaultView.getComputedStyle(w3c)或者元素的currentStyle属性(ie)来获取浏览器计算后的正确样式。

如:

function getStyle(el,name){
        var value=el.style[name];
        if(!value){
            //w3c
            if(document.defaultView&&document.defaultView.getComputedStyle){
                var css=document.defaultView.getComputedStyle(el,null);
                value=css?css.getPropertyValue(name):null;
            }
            //ie
            else if(el.currentStyle){
                value=el.currentStyle[name];
            }
        }
        return value=='auto'?'':value;
    }

其实改变样式往往用的更多的是操作类,通过类来指定样式,这样便于维护,也符合表现(css)与行为(js)相分离的编程思想。

css.js暂时模拟了jquery的css方法以及 addClass、removeClass、hasClass、以及toggle方法。还把一开始的hide与show方法移到了css.js里面因为这2个方法也是操作的样式。

css.js

    /*!Css 样式修改
     *
     *Date   2014-4-13
     *author meng
    */
(function(_window){
    //定义css方法 根据参数类型与个数实现不同功能
    //css(name),则返回样式名为name的样式值
    //css(name,val),设置样式名name的样式值为value
    //css(name,fun),设置样式名为name的样式值为fun函数的返回值
    //css({property:value, property:value, ...}),把“名/值对”设置为样式属性
    _window.MQuery.fn.css=function(cssarg){
        if(this.elements.length<=0) return;
        var length=arguments.length,
        //参数1 要么为设置样式的名称 要么是一个参数名称与参数值的键值对 
        arg1=arguments[0],
        //参数2 要么是设置的值 要么是一个函数
        arg2=arguments[1];

        if(length==0||!arg1)
            throw new Error("css 方法参数不能为空")
        //1个参数
        if(length==1){
            //css("name") 
            if(typeof(arg1)=="string"){
                return getStyle(this.elements[0],arg1);
            }
            //css({property:value, property:value, ...})
            else if(typeof(arg1)=="object"){
                for(v in arg1){
                    this.each(function(x){
                        setStyle(x,v,arg1[v]);
                    });
                }
            }
        }
        else if(length==2){
            var val='';
            //css("name","val")
            if(typeof(arg1)=="string"&&typeof(arg2)=="string"){
                val=arg2;
            }
            //css("name",fun)
            else if(typeof(arg1)=='string'&&typeof(arg2)=='function'){
                val=arg2();
            }
            this.each(function(x){
                setStyle(x,arg1,val);
            });
            return this;
        }
    }

    //以下定义了 addClass,removeClass,hasClass,toggle 如果有classlist属性则直接使用classlist 否则自己实现
    _window.MQuery.fn.addClass=function(className){
        this.each(function(x){
            if(x.classList){
                x.classList.add(className);
            }
            else{
                if(!hasClassName(x,className)){
                    addClassName(x,className);    
                }
            }
        })
    }

    _window.MQuery.fn.removeClass=function(className){
        this.each(function(x){
            if(x.classList){
                x.classList.remove(className);
            }
            else{
                if(hasClassName(x,className)){
                    removeClassName(x,className);
                }
            }
        })
    }

    _window.MQuery.fn.hasClass=function(className){
        if(this.length==0){return;}
        var el=this.elements[0];
        if(el.classList){
            return el.classList.contains(className);
        }
        else{
            return hasClassName(el,className);
        }
    }
    //如果存在className则移除className,否则增加className
    _window.MQuery.fn.toggle=function(className){
        this.each(function(x){
            if(x.classList){
                x.classList.toggle(className);
            }
            else{
                if(hasClassName(x,className)){
                    removeClassName(x,className);
                }
                else{
                    addClassName(x,className)
                }
            }
        })
    }

    //define hide
    MQuery.fn.hide=function(){
        this.each(function(e){
            e.style.display='none';
        });
    }
    //define show
    MQuery.fn.show=function(){
        this.each(function(e){
            e.style.display='';
        });
    }
    //以下为私有方法
    //移除类
    function removeClassName(el,className){
        var classNameArry=el.className.split(' ');
        for(var i=0;i<classNameArry.length;i++){
            if(classNameArry[i]==className){
                classNameArry.splice(i,1);
            }
        }
        el.className=classNameArry.join(' ');
    }
    //判断是否已存在类
    function hasClassName(el,className){
        var classNames=el.className.split(' ');
        for(var i=0;i<classNames.length;i++){
            if(classNames[i]==className){
                return true;
            }
        }
        return false;
    }
    //增加类
    function addClassName(el,className){
        el.className+=(' '+className);
    }
    //获取一个元素的最终样式
    function getStyle(el,name){
        var value=el.style[name];
        if(!value){
            //w3c
            if(document.defaultView&&document.defaultView.getComputedStyle){
                var css=document.defaultView.getComputedStyle(el,null);
                value=css?css.getPropertyValue(name):null;
            }
            //ie
            else if(el.currentStyle){
                value=el.currentStyle[name];
            }
        }
        return value=='auto'?'':value;
    }
    //设置元素的样式
    function setStyle(el,name,val){
        el.style[name]=val;
    }
})(window)

html

<!DOCTYPE html>
<html>
    <head>
        <title>mquery</title>
        <style>
            body .p{
                width: 150px;
                height: 50px;
                margin-bottom: 20px;
                padding: 20px;
            }
            .borderred{
                border:1px solid red;
            }
            .padding{
                padding: 20px;
            }
        </style>
        <script type="text/javascript" src="../core/sizzle.js"></script>
        <script type="text/javascript" src="../core/mquery.js"></script>
        <script type="text/javascript" src="../core/css.js"></script>
    </head>
    <body>
        <p class="p">ppppp1</p>
        <p class="p">ppppp2</p>
        <script type="text/javascript">
            var p = $("p");
            p.css("width",'300px').css({"height":'300px',"color":'red'});
            p.css("background-color",function(){return "black"});
            p.css("background-color","#fff");
            console.log('hasborderred:'+p.hasClass("borderred"));
            p.addClass("borderred");
            console.log('hasborderred:'+p.hasClass("borderred"));
            p.removeClass("borderred");
            console.log('hasborderred:'+p.hasClass("borderred"));
            p.toggle("padding");
            console.log('haspadding:'+p.hasClass("padding"));
            p.toggle("padding");
            console.log('haspadding:'+p.hasClass("padding"));
        </script>
    </body>
</html>
原文地址:https://www.cnblogs.com/xiaopi/p/3663254.html