前面的話
我們可以通過計算樣式來讀取偽元素的樣式信息,但是卻無法使用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】腳本化偽元素
歡迎交流