• JavaScript DOM高级程序设计 5动态修改样式和层叠样式表2--我要坚持到底!


    把样式置于DOM脚本之外

    • style属性

    我们可以这样设置前景色之类的属性:

    element.style.color='red';

    也可以使用下面的代码设置背景颜色:

    element.style.backgroundColor='red';
    

    将background-color转换为驼峰形式大小写形式的backgroundColor(删除连接字符串并将后续单词的首字母变成大写)是必须的,DOM2样式规范为CSSStyleDeclaration对象定义了相应的方法,比如setProperty()就使用固有的带连字符的CSS属性名称和值(但是ie不支持):

    element.style.setProperty('background-color','red');

    为了不针对环境,将setStyleById(),setStyleByClassName(),setStylsByTagName()方法添加到ADS库中。

    /**
     *通过ID修改单个元素的样式
     */
    function setStyleById(element, styles) {
        //取得对象的引用
        if(!(element = $(element))) return false;
        //循环遍历styles对象并应用每个属性
        for (property in styles) {
            if(!styles.hasOwnProperty(property)) continue;
        
            if(element.style.setProperty) {
                //DOM2样式规范方法
                element.style.setProperty(
                uncamelize(property,'-'),styles[property],null);
            } else {
                //备用方法
                element.style[camelize(property)] = styles[property];
            }
        }
        return true;
    }
    window['ADS']['setStyle'] = setStyleById;
    window['ADS']['setStyleById'] = setStyleById;
    
    /**
     * 通过类名修改多个元素的 样式
     */
    function setStylesByClassName(parent, tag, className, styles) {
        if(!(parent = $(parent))) return false;
        var elements = getElementsByClassName(className, tag, parent);
        for (var e = 0 ; e < elements.length ; e++) {
            setStyleById(elements[e], styles);
        }
        return true;
    }
    window['ADS']['setStylesByClassName'] = setStylesByClassName;
    
    /**
     * 通过标签名修改多个元素的样式
     */
    function setStylesByTagName(tagname, styles, parent) {
        parent = $(parent) || document;
        var elements = parent.getElementsByTagName(tagname);
        for (var e = 0 ; e < elements.length ; e++) {
            setStyleById(elements[e], styles);
        }
    }
    window['ADS']['setStylesByTagName'] = setStylesByTagName;
    /**实例
     ADS.setStylesByClassName(
        'findclass',
        '*',
        document,
        {'background-color':'red'}
     )
     或者
    
     ADS.setStylesByTagName('a',{'text-decoration':'underline'});
    */

    基于className切换样式

    对于中小范围的表现变化,例如只影响少数元素的颜色、边框、背景和字体,可以通过切换className来避免在代码中苦苦寻找样式属性。

    使用className切换方法可以维护适当的分离,并且为CSS设计者打开了使用样式表设计网站表现的大门。下面将操纵classname的方法添加到ADS库中

    /*取得包含元素类名的数组*/
    function getClassNames(element) {
        if(!(element = $(element))) return false;
        //用一个空格替换多个空格,然后给予空格分割类名
        return element.className.replace(/s+/,' ').split(' ');
    };
    window['ADS']['getClassNames'] = getClassNames;
    
    /*检查元素是否存在某个类*/
    function hasClassName(element, className) {
        if(!(element = $(element))) return false;
        var classes = getClassNames(element);
        for (var i = 0; i < classes.length; i++) {
           //检测className是否匹配,如果是则返回true
            if (classes[i] === className) { return true; }
        }
        return false;
    };
    window['ADS']['hasClassName'] = hasClassName;
    
    
    /*为元素添加类*/
    function addClassName(element, className) {
        if(!(element = $(element))) return false;
        //将类名添加到当前className的末尾,如果没有className,则不包含空格
        element.className += (element.className ? ' ' : '') + className;
        return true;
    };
    window['ADS']['addClassName'] = addClassName;
    
    /*从元素中删除类*/
    function removeClassName(element, className) {
        if(!(element = $(element))) return false;
        var classes = getClassNames(element);
        var length = classes.length
       //循环遍历数组删除匹配的项
        //因为从数组中删除项会使数组变短,所以要反响循环
        for (var i = length-1; i >= 0; i--) {
            if (classes[i] === className) { delete(classes[i]); }
        }
        element.className = classes.join(' ');
        return (length == classes.length ? false : true);
    };
    window['ADS']['removeClassName'] = removeClassName;
    
    
    /*
    方便的取得与一个元素关联的所有累
    var element=document.getElementById('example');
    var classes=ADS.getClassName(element);
    var class;
    for (var i = 0;class=class[i];i++)
    {
        //对每个类进行操作
    }
    
    或者在向元素添加类名之前检查是否存在该雷鸣,以便实现切换效果
    function toggleClassName(element,className)
    {
        if(!)ADS.hasClassName(element,className)
        {
            ADS.addClassName(element,className);
        }
        else
        {
            ADS.removeClassName(element,className);
        }
    }
    ADS.addEvent('toggleButton','click',function(){
        toggleClassName(this,'active')
    });
    
    甚至还能通过使用适当的事件侦听器和hover类生成翻转效果
    var element=document.getElementById('example');
    ADS.addEvent(element,'mouseover',function(){ADS.addClassName(this,'hover');});
    ADS.addEvent(element,'mouseout',function(){ADS.removeClassName(this,'hover')});
    */
    • 切换样式表
    1. 可以使用<link>元素的rel属性定义备用的样式表,并在他们之间进行切换。
    2. 可以为body标签应用一个类,并根据这个类修改CSS选择符--实际上是以body标签做为跟元素的className切换
    3. 可以动态添加或移除样式表
    • 使用备用样式表

    如果你始终遵守表现与标记分离原则,那你一定熟悉<link>元素:<link type="text/css" href="style.css" media="screen"/>

    <link>元素包含一下属性:(和我们本章开始介绍的CSSStyleSheets类似)

    • type:text/css
    • href:指定样式的位置
    • media:限制样式设备类型

    这些是常用的,另外还有

    • ref:表示样式与文档之间的关系
    • disable:表示样式是否起作用
    • title:表示与样式表关联的标题

    下面讲一个说一个实例,源代码在上一节的chapter5中,switcher/example.html中,在这个例子中公共CSS问津没有设置title属性,而friends of ED和Apress样式都有一个相应的样式表文件,标记中空列表元素:

      <ul id="styleSwitcher"></ul>

    是由styleSwitcher.js文件通过load事件处理程序,在备用的样式表文件及其title属性的基础上动态生成的:(其实这个例子看起来听神奇的。)

    ADS.addEvent(window,'load',function(){
        //取得所有link元素
        var list=ADS.$('styleSwitcher');
        var links=document.getElementsByTagName('link');
        var titles=[];
    
        for(var i=0;i<links.length;i++)
        {
            //跳过不带title属性的<link>元素
            if (links[i].getAttribute("rel").indexOf("style")!=-1
                &&links[i].getAttribute("title"))
            {
                //如果该样式表还未添加则想列表中添加一个新项
                var title=links[i].getAttributes("title");
                if (!titles[title])
                {
                    var a = document.createElement('a');
                    a.appendChild(document.createTextNode(title));
                    a.setAttribute('href'.'#');
                    a.setAttribute('title','Activate'+title);
                    a.setAttribute('rel',title);
                    ADS.addEvent(a,'click',function(){
                        //单击激活链接是激活锚的rel属性中的标题所表示的样式
                        setActiveStyleSheet(this.getAttribute('rel'));
                        ADS.preventDefault(W3CEvent);
                    });
    
                    var li = document.createElement('Li');
                    li.appendChild(a);
                    list.appendChild(li);
    
                    //将title数组中的这个标题项设置为true。一边在多样式使用相同的标题跳过
                    title[title]=true;
                }
            }
        }
    });
    • 切换body元素的className

    这种方法的知道思想和上面类似,只不过是body标签的className

    /*公共样式*/
    
    body{}
    #container{}
    /*AdvancED DOM Scripting 样式*/
    body.ads{}
    body.ads h1{}
    body.ads h2{}
    
    /*friends of ED 样式*/
    body.foed{}
    body.foed h1{}
    body.foed h2{}
    
    /*其他样式*/
    /*Apress样式*/
    body.apress{}
    body.apress h1{}
    body.apress h2{}

    然后用本章前面的ADS库,你可以动态的勤换body标签的类名,而CSS规则会在相应的修改页面表现:

    ADS.addEvent('ads-anchor','click',function(){
        ADS.addClassName(document.body,'asd');
    });
    ADS.addEvent('foed-anchor','click',function(){
        ADS.addClassName(document.body,'foed');
    });
    ADS.addEvent('apress-anchor','click',function(){
        ADS.addClassName(document.body,'apress');
    });
    • 动态载入和移除样式

    相当直观,使用这种技术索要做的就是通过document.createElement()及适当的属性<link>

    /*添加新样式表*/
    function addStyleSheet(url,media)
    {
        media=media||'screen';
        var link=document.creatElement('LINK');
        link.settAttribute('rel','stylesheet');
        link.settAttribute('tyle','text/css');
        link.settAttribute('href','url');
        link.settAttribute('media','media');
        document.getElementsByTagName('head')[0].appendChild(link);
    }
    window['ADS']['addStyleSheet']=addStyleSheet
    /*移除样式表*/
    function removeStyleSheet(url,media)
    {
        var styles=getStyleSheets(url,media);
        for (var i = 0;i<style.length ;i++ )
        {
            var node=styles[i].ownerNode||styles[i].owningElement;
            //禁用样式
            styles[i].disabled=ture;
            //移除节点
            node.parentNode.removeChild(node);
        }
    }
    
    window['ADS']['removeStyleSheet']=removeStyleSheet
    /**实例
    ADS.addStyleSheet('/path/style.css','screen');
    ADS.removeStyleSheet('/path/style.css','screen');
    */
    • 修改CSS规则

    在ADS库中添加方法,他能帮助你从document.styleSheets列表中查找带有适当的href和media属性的样式表:

    /*通过URL取得包含所有样式表的数组*/
    function getStyleSheets(url,media) {
        var sheets = [];
        for(var i = 0 ; i < document.styleSheets.length ; i++) {
            if (url &&  document.styleSheets[i].href.indexOf(url) == -1) { continue; }
            if(media) {
                //规范化media字符串
                media = media.replace(/,s*/,',');
                var sheetMedia;
                    
                if(document.styleSheets[i].media.mediaText) {
                   //DOM方法
                    sheetMedia = document.styleSheets[i].media.mediaText.replace(/,s*/,',');
                   //Safari会添加额外的都和和空格
                    sheetMedia = sheetMedia.replace(/,s*$/,'');
                } else {
                    // MSIE
                    sheetMedia = document.styleSheets[i].media.replace(/,s*/,',');
                }
                // 如果media不匹配则跳过
                if (media != sheetMedia) { continue; }
            }
            sheets.push(document.styleSheets[i]);
        }
        return sheets;
    }
    window['ADS']['getStyleSheets'] = getStyleSheets;

    现在找到目标样式表了,但是还需要想库中添加ADS.editCSSRule()和ADS.addCSSRule()方法才能修改其中的样式规则:

    /**
     * 编辑一条样式表规则
     */
    function editCSSRule(selector,styles,url,media) {
        var styleSheets = (typeof url == 'array' ? url : getStyleSheets(url,media));
    
        for ( i = 0; i < styleSheets.length; i++ ) {
    
            //取得规则表
            // DOM2样式规范方法是 styleSheets[i].cssRules
            // MSIE规范方法是styleSheets[i].rules
            var rules = styleSheets[i].cssRules || styleSheets[i].rules;
            if (!rules) { continue; }
                   
            // 由于MSIE默认使用大小写故转换为大写形式
            // 如果你使用的是区分大小写的id,则可能导致冲突
            selector = selector.toUpperCase();
            
            for(var j = 0; j < rules.length; j++) {
                // 检查是否匹配
                if(rules[j].selectorText.toUpperCase() == selector) {
                    for (property in styles) {
                        if(!styles.hasOwnProperty(property)) { continue; }
                        // 设置新的样式属性
                        rules[j].style[camelize(property)] = styles[property];
                    }
                }
            }
        }
    }
    window['ADS']['editCSSRule'] = editCSSRule;
    /*ADS.editCSSRule('a',{'background-color':'yellow'});*/
    
    
    /**
     * 增加一条CSS样式
     */
    function addCSSRule(selector, styles, index, url, media) {
        var declaration = '';
    
        // 根据style参数构建声明字符串
        for (property in styles) {
            if(!styles.hasOwnProperty(property)) { continue; }
            declaration += property + ':' + styles[property] + '; ';
        }
    
        var styleSheets = (typeof url == 'array' ? url : getStyleSheets(url,media));
        var newIndex;
        for(var i = 0 ; i < styleSheets.length ; i++) {
            // 添加规则       
            if(styleSheets[i].insertRule) {
                // DOM2样式规范的方法
                // index = length 是列表的结尾
                newIndex = (index >= 0 ? index : styleSheets[i].cssRules.length);
                styleSheets[i].insertRule(selector + ' { ' + declaration + ' } ', 
                    newIndex);
            } else if(styleSheets[i].addRule) {
                // MS的方法
                // index = -1 是列表的结尾 
                newIndex = (index >= 0 ? index : -1);
                styleSheets[i].addRule(selector, declaration, newIndex);
            }
        }
    }
    window['ADS']['addCSSRule'] = addCSSRule;
    /**
    ADS.addCSSRule('a[href]:after',{
        'content':'"("attr(href)")"';
        'font-size':'40%',
        'color':'#16009b'
    });
    */
    • 访问计算样式

    DOM2样式规范在document.defaultView中包含了一个名叫getComputedStyle()的方法,就是为了访问计算样式而设计的。该方法返回一个制度的CSSStyleDeclaration对象。

    在取得给定元素的计算样式之后,可以通过与操作元素的style属性一样的方式来取得信息

    var element=ADS.$('example');
    var styles=document.defaultView.getComputedStyle(element);

    取得background-color值需要下面这样简单:

    var color=styles.getProperty('background-color');

    我们在库中添加如下代码:

    /*取得一个元素的计算样式*/
    function getStyle(element,property)
    {
        if (!element=$(element)||!property) return false;
        
        //检测元素style属性的的值
        var value=element.style[camelize(property)];
        if(!value)
        {
            //计算取得样式的值
            if (document.defaultView&&document.defaultView.getComputedStyle)
            {
                //DOM
                var css=document.defaultView.getComputedStyle(element,null);
                value=css?css.getPropertyValue(property):null;
            }
            else if (element.currentStyle)
            {
                MSIE的方法
                value=element.currentStyle[camelize(property)];
            }
        }
    
        //返回空字符串而不是auto这样就不必检查auto值了
        return value=='auto'?'':value;
    }
    window['ADS']['getStyle']=getStyle;
    window['ADS']['getStyleById']=getStyle;
  • 相关阅读:
    在虚拟机上安装Docker并运行镜像下
    分红包思想
    从微信授权到JWT认证——玩转token之路
    .Net(C#)数据库访问连接方式
    Asp.Net导出Excel表格之二(HttpContext.Current.Response)
    我的ip_本机ip_本地ip_本机ip地址_公网ip_ip地址查询
    干货版“测试小品”欢乐场景
    家用宽带搭建Hmailserver邮箱服务器
    【microPython与esp8266】之一——呼吸灯与PWM
    截取长文本,显示省略号(text-overflow:ellipsis)
  • 原文地址:https://www.cnblogs.com/sunhan/p/3542401.html
Copyright © 2020-2023  润新知