深入理解腳本化CSS系列第六篇——腳本化偽元素的6種方法


前面的話

  我們可以通過計算樣式來讀取偽元素的樣式信息,但是卻無法使用javascript來直接操作偽元素,本文以一個需求解決為例,詳細介紹腳本化偽元素的6種方法

需求說明

  【1】為id=box的div元素添加content="前綴"的:before偽元素

  【2】為已經添加:before偽元素的div元素刪除偽元素

   [注意]由於IE7-瀏覽器不支持:before偽元素,所以該需求兼容到IE8

 

添加偽元素

動態樣式

  可以采用動態樣式的方法,動態生成<style>標簽及相關的偽元素樣式內容

  由於IE8-瀏覽器將<style>標簽當作特殊的節點,不允許訪問其子節點及設置innerHTML屬性,需要使用CSSStyleSheet對象的cssText屬性來實現兼容

<div id="box">測試文字</div>
<button id="btn">添加偽元素</button>
<script>
//添加偽元素
function loadStyles(str){
    //設置標記,防止重復添加
    loadStyles.mark = 'load';
    var style = document.createElement("style");
    style.type = "text/css";
    try{
        style.innerHTML = str;
    }catch(ex){
        //IE8-瀏覽器兼容
        style.styleSheet.cssText = str;
    }
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(style); 
}
btn.onclick = function(){
    //當樣式表沒有添加過時,添加
    if(loadStyles.mark != 'load'){
        loadStyles("#box:before{content:'前綴';color: red;}");        
    }
}
</script>        

添加自帶偽元素的類名

  在處理大量CSS樣式時,一般采用腳本化CSS類的方法。而添加偽元素,也可以使用類似的技術。把偽元素的樣式掛在一個新類名上,然后把元素的className設置為新類名

<style>
.add:before{content: "前綴";color: blue;}    
</style>

<div id="box">測試文字</div>
<button id="btn">添加偽元素</button>
<script>
btn.onclick = function(){
    box.className = 'add';
}
</script>

利用setAttribute()方法實現自定義偽元素內容

  若使用方法二,無法自定義偽元素的內容,拓展性不高

  偽元素的content屬性非常強大,它的值可以有以下選擇,關於content屬性的詳細信息移步至此

content:<string>|<uri>|attr(<identifier>)

  使用content屬性中的attr()值配合setAttribute()方法就可以實現自定義偽元素的內容

  IE8-瀏覽器需要在元素特性中出現data-beforeData(設置為空字符串即可),才有效果;其他瀏覽器無此問題

<style>
#box:before{content: attr(data-beforeData);color: red;}
</style>

<!--為了兼容IE8-,需要在元素特性中設置 data-beforeData=""--> <div id="box" data-beforeData="">測試文字</div> <button id="btn">添加偽元素</button> <script> btn.onclick = function(){ box.setAttribute('data-beforeData','前綴'); } </script>

dataset

  HTML5新增了dateset數據集特性,將元素特性和對象屬性聯系在了一起

  [注意]IE10-瀏覽器不支持

  如果不考慮兼容,同樣可以實現dateset來實現,但是由於dataset的解釋規則,元素特性的值不可以出現大寫,需要進行局部修改

  經測試,IE11瀏覽器不支持使用dateset動態修改偽元素

<style>
#box:before{content: attr(data-before);color: red;}
</style>

<div id="box">測試文字</div>
<button id="btn">添加偽元素</button>
<script>
btn.onclick = function(){
    box.dataset.before = '前綴';
}
</script>

通過CSSRule對象添加樣式

  雖然偽元素的樣式無法通過操作行間樣式來直接添加,但是可以通過CSSRule對象通過操作內部樣式表實現

  如果存在內部樣式表,即存在<style>標簽,則直接在<style>標簽中添加樣式;否則先新建<style>標簽,再添加樣式

<div id="box">測試文字</div>
<button id="btn">添加偽元素</button>
<script>
//作為存在<style>標簽的標記,1表示存在,0表示不存在
var mark = 0;
var tags = document.getElementsByTagName('*');
function addStyle(obj){
    var str = '#box:before{content:"前綴";color: pink;}';
    var sheet = obj.sheet || obj.styleSheet;
    var rules = sheet.cssRules|| sheet.rules;
    for(var i = 0,len = rules.length; i < len; i++){
        //如果已經設置了:before偽元素的樣式,就不再重復添加
        if(/:before/.test(rules[i].selectorText)){
            //obj.mark表示是否設置了:before偽元素的樣式,1為已設置,0為未設置
            obj.mark = 1;
            break;
        }
    }
    //如果未設置偽元素樣式
    if(!obj.mark){
        if(sheet.insertRule){
            sheet.insertRule('#box:before{content:"前綴";color:green;}',0);
        }else{
            sheet.addRule('#box:before','content:"前綴";color:green;',0);
        }
    }
}
btn.onclick = function(){
    for(var i = 0; i < tags.length; i++){
        if(tags[i].nodeName == 'STYLE'){
            mark = 1;
            //添加偽元素
            addStyle(tags[i]);
            break;
        }
    }
    if(!mark){
        //新建<style>標簽
        var ele = document.createElement('style');
        document.getElementsByTagName('head')[0].appendChild(ele);
        //添加偽元素
        addStyle(ele);
    }    
}
</script>    

 

刪除偽元素

  相比於新增偽元素來說,刪除偽元素要困難一些。因為<style>元素中可能還有許多其他的樣式,所以只能通過覆蓋或刪除指定樣式來實現

空樣式覆蓋

  使用優先級更高的:before偽元素的空樣式來覆蓋原有樣式

<style>
#box:before{content:"前綴";color:green;}    
.remove:before{content:""!important;}
</style>

<div id="box">測試文字</div>
<button id="btn">刪除偽元素</button>
<script>
btn.onclick = function(){
    box.className = 'remove';    
}
</script>    

通過CSSRule對象刪除指定

  通過selectorText找出CSSRule對象中的:before偽元素的CSS規則

  [注意]在IE8瀏覽器中,:before偽元素選擇器文本會自動將冒號置為單冒號,而其他瀏覽器會自動將冒號置為雙冒號

  然后使用deleteRule()方法或removeRule()方法刪除指定樣式

<style>
#box::before{content:"前綴";color:green;}    
</style>

<div id="box">測試文字</div>
<button id="btn">刪除偽元素</button>
<script>
function deleteStyles(){
    var sheet = document.styleSheets[0];
    var rules = sheet.cssRules || sheet.rules;
    for(var i = 0; i < rules.length; i++){
        //找出偽元素
        if(/#box:(:)?before/.test(rules[i].selectorText)){
            if(sheet.deleteRule){
                sheet.deleteRule(i);
            //兼容IE8-瀏覽器
            }else{
                sheet.removeRule(i);
            }    
        }
    }
}
btn.onclick = function(){
    deleteStyles();    
}
</script>

 

最后

  腳本化CSS系列終於完結了,基本上把使用javascript操作CSS的內容都囊括了

  【1】腳本化行間樣式

  【2】查詢計算樣式

  【3】腳本化CSS類

  【4】腳本化樣式表

  【5】動態樣式

  【6】腳本化偽元素

  歡迎交流


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM