天天看点

[Javascript]:DOM操作之动态修改CSS样式和高级选择器

首选,回顾一下CSS定义样式的三种方式:链接外部样式、嵌入样式(放在head元素中)和内联样式(行内样式)。想要让样式生效,有如下方式:

  • 通过CSS选择器来进行大规模选取,但通常会用到ID属性和class属性来指定范围。
  • 通过ID和class属性来设置样式。
  • 直接定义内联样式,直接作用于当前标签。
  • 当然,有些标签提供了样式属性,但不推荐使用。结构与表现应该分开。

但CSS样式是静态的,要让CSS样式动态化,就需要使用JS的DOM操作。例如网页的开灯关灯效果,就需要使用JS来完成。JS修改CSS样式的几种方式:

通过ID和class属性修改css样式

  • 这里用到DOM节点的节点属性:id和className。
<style>
        /* 减少代码占行... */
        .style{ height: 300px; width: 300px; background-color: yellowgreen;}
        .style2{ height: 200px; width: 100px; background-color: red; }
        #div2{ height: 150px; width: 200px;   background: pink;} 
    </style>
</head>
<body> 
    <div id="div1" class="">
    </div>
    <button οnclick="aa()">点击修改CSS样式</button>
    <button οnclick="bb()">再次修改CSS样式</button>
    <button οnclick="cc()">CSS样式不可见</button>
    <script>
        function aa(){
            document.getElementById("div1").className = "style"; //修改class属性为style
        }
        function bb(){
            document.getElementById("div1").className = "style2"; //修改class属性为style2
        }
        //修改ID属性来更换CSS样式
        function cc(){
            var te = document.getElementById("div1"); //拿到div1的元素节点
            te.id = "div2"; //修改ID属性
            //2s后ID属性复原。不然其他两个函数获取不到原id属性
            window.setTimeout(function(){
                te.id  = "div1"
            }, 2000);
        }
    </script>
           

使用注意:

  • ID属性作为唯一标识,如果用ID属性来动态修改CSS样式就意味着会修改ID属性,这会导致用原ID属性来获取元素节点的函数找不到,除非定个时限,多久后将ID属性值复原。所以通过ID属性来动态修改样式不推荐使用,很容易引发问题。还有定时器函数,不推荐直接写执行代码,有时会解析不了,估计和eval()差不多,所以需要把执行代码放在匿名函数中,这样执行函数就没问题了。
  • 因为class可以存在多个属性,所以用class属性来指定不同样式,实现动态样式是非常方便的。

使用style节点属性修改CSS样式

  • style作为内联样式,优先级只比!important指定的样式低一级,这意味着如果存在同类型样式,那么原有样式会被style覆盖掉,所以要注意。
  • 如果使用element.style则返回:CSSStyleDeclaration,表示一个对象,而不是字符串。所以除了直接字符串赋值形式,还可以通过style对象的一些属性和方法来设置CSS样式。

第一种:拿到style属性,直接赋值。典型的element.attribute格式设置值。

<style>
        /* 减少代码占行... */
        .style{ height: 300px; width: 300px; background-color: yellowgreen;}
        .style2{ height: 200px; width: 100px; background-color: red; }
        #div1{ height: 150px; width: 200px;   background: pink;  } 
    </style>
</head>
<body> 
    <div id="div1">
       <p>用来测试的文本1</p>
       <p>用来测试的文本2</p>
    </div>
    <button οnclick="alterColor()">修改div的文本颜色</button>
    <button οnclick="addHW()">增加高和宽</button>
    <script>
        //把指定元素节点中的文本颜色变成红色
        function alterColor(){
            var div1 = document.getElementById("div1");
            div1.style = "color:red"; 
        }
        //给指定元素节点增加高和宽
        function addHW(){
            var div1 = document.getElementById("div1");
            //覆盖原样式的高度、宽度
            div1.style = "height:500px; width:300px; border: 1px solid red;"; 
        }
    </script>
           

使用说明:编辑器不会提示样式补全,所以需要记住各种样式名称和样式值。也可以先用编辑器的CSS提示功能获取需要动态修改的样式,然后复制粘贴。

第二种:调用style属性的样式属性

//style对象中定义了许多常用的样式属性。但是不推荐这种方式,太麻烦,每次只能设置一个样式。
div1.style.height = "50px";
div1.style.weight = "50px";
div1.style.backgroundColor = "blue";
           

第三种:调用style属性的cssText

  • 使用方式和直接给style属性赋值差不多。用那个看你心情了。
//使用cssText设置css样式
div1.style.cssText = "height:50px; width:100px; border: 1px solid red;";
           

style对象还有以下方法常用方法来处理CSS样式:

  • getPropertyValue(string):返回指定声明的值
  • setProperty(属性名, 属性值, 样式优先级) 设置指定的CSS属性;
  • removeProperty(string):用于删除一条CSS属性,返回被删除的值;
  • length:返回该style中有多少条样式声明。

使用DOM操作属性节点修改CSS样式

上面通过id、class和style属性来修改CSS样式其实都是属于操作属性节点范围。通过setAttribute()也可以做到以上方式,例如:

div1.setAttribute('style', 'height:150px; width:150px; border: 1px solid red;'); //修饰元素节点的style属性
 div1.setAttribute('class', 'style2'); //修改元素节点的class属性
 div1.setAttribute("id", "div2") //修改元素节点的ID属性
 alert(div1.getAttribute("style")); //可以以字符串形式返回sytle的样式值
           

通过设置属性这种方式来修改CSS样式就显得过于麻烦,不推荐这样使用。

操作属性节点修改CSS样式,通常用于更改link引入的CSS外部文件地址。这样可以做到更换整体样式:

<link rel="stylesheet" href="abc.css" target="_blank" rel="external nofollow"  id="fristlink">
</head>
<body>
    <button οnclick="ss()">改变引入的样式表,修改样式</button>
    <script>
        function ss(){
            var link = document.getElementById("fristlink"); //拿到link元素节点
            link.setAttribute("href", "test.css");//改变当前引用的外部CSS文件
        }
           

但这种方式只能基于文档已经存在了外部CSS文件的链接标签。 如果想对一个没有指定任何样式的网页动态添加一个外部CSS文件和嵌入样式可以采用下面方式。

动态添加链接样式和嵌入样式

如果没有引入外部CSS文件,那就创建一个link,然后添加进去。

var link = document.createElement("link"); //创建一个link元素节点
           link.setAttribute("rel", "stylesheet");
           link.setAttribute("href", "test.css");
           //添加至head元素节点的尾部
           document.getElementsByTagName("head")[0].appendChild(link);
           

创建一个新的嵌入样式<style>和上面差不多,如下:

var sty = document.createElement("style"); //创建一个style元素节点
           sty.setAttribute("type", "text/css");
           //文本节点形式创建CSS样式,采用innerText会覆盖原有样式。
           var css = document.createTextNode(" body { background-color:red; } ");
           sty.appendChild(css); //将文本节点添加到sty节点的尾部
           //添加至head元素节点的尾部
           document.getElementsByTagName("head")[0].appendChild(sty);
           

这种方式基本用不到,了解即可。

了解了动态添加链接样式和嵌入样式,是不是还想到了动态添加script脚本,有的时候我们不想让script预先加载,而是等页面加载完成后再加载,使用方式就和上面的用法差不多。这里就不给出例子了,可以自行测验。

querySelector 和 querySelectorAll 的使用方式

在DOM中,常规获取元素节点方式就那4个,但只需要掌握CSS选择器语法规则,通过这两个方法就能非常快捷的定位相关元素。

querySelector和querySelectorAll的区别:

  • querySelector只返回一个对象,如果查询到多个元素,也只返回第一个。
  • querySelectorAll返回一个对象集合,和getElementsXxx系列差不多。

和常规获取元素方式的对比,使用起来差不多。

//查询id
        document.getElementById("div1");
        document.querySelector("#div1"); //#div1 找到 id = div1的元素节点
        //查询class
        document.getElementsByClassName("div2"); //返回集合对象
        document.querySelectorAll(".div2"); //返回集合
        document.querySelector(".div2")//等同于: document.querySelectorAll("div2")[0]
           

拿到某个元素节点下的所有a元素。

//常规获取方式
        var div1 = document.getElementById("div1"); //查询id
        var as = div1.getElementsByTagName("a"); //拿到指定元素下的所有a元素
      
        //获取id = div1 元素下的所有a元素  使用了后代选择器
        var ad = document.querySelectorAll("#div1 a");
           

如果选择器规则改成 “#div1 > a” ,那么包含在其他元素中的a元素就获取不了了。所以使用这两种方法需要详细掌握CSS选择器的各种语法规则。

批量设置h2 、h3、h4元素的字体颜色

//这里使用其他获取方式都很麻烦,class是最简便的。
        var tt = document.getElementsByClassName("aaa"); //h2 h3 h4 h5自己去设置,class都为aaa。
        for(var i = 0; i < tt.length; i++){
            tt[i].style = "color: red";
        }
        //使用群组选择器,查询相关元素节点
        var ad = document.querySelectorAll("h2, h3, h4, h5"); 
        for(var i = 0; i < ad.length; i++){
            tt[i].style = "color: blue";
        }
           

只要是能通过CSS选择器定义的样式,通过该方法也可以定位该元素。而且结构层次越复杂,则这两个方法的优势就会越大。所以要掌握好这两个方法,必须得掌握好CSS选择器。关于CSS选择器的知识详解,点击: CSS选择器详解。