天天看點

[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選擇器詳解。