摘要:利用方法選擇到偽元素,然后利用方法獲取對應的屬性的值。具體用法可以參考的這篇文章而偽元素的屬性值除了常規賦值外,還有一種特殊的方法來獲取。具體實現參照,不再做具體分析參考文獻獲取元素值之方法熟悉
雖然標題里寫的是偽元素,不過這篇文章主要是說::before和::after,其余幾個偽元素(::first-letter、::first-line、::selection等)由于沒有content屬性,所以本文一筆帶過,其實方法是一樣的。
偽元素的重點在于一個偽,雖然它們可以被瀏覽器渲染引擎識別并正確渲染,然而偽元素本身并不是DOM元素,所以無法被js直接操作——因此任何基于JS直接選取DOM元素的CSS更改方法對偽元素都不起作用。(JQ看似萬能,這個問題上是直接就栽了。因為JQ的選擇符都是基于DOM元素)關于JS和JQ選擇器,可以參考這兩篇文檔: Selectors API Level 1、jQuery Selectors
雖然JS里沒有可以直接操作偽元素的選擇符,然而獲取其CSS屬性的方法還是有的。
window.getComputedStyle利用window.getComputedStyle方法選擇到偽元素,然后利用getPropertyValue方法獲取對應的屬性的值。
根據MDN的文檔,
window.getComputedStyle(element[, pseudoElt]);
此方法包含兩個參數,一個是元素本身另一個是元素的偽元素。
js語法實例(完整DEMO在線鏈接):
var div=document.querySelector("div"); var fontSize=window.getComputedStyle(div,"::before").getPropertyValue("font-size");//獲取before偽元素的字號大小
關于這個方法,詳解可以參考這篇文章:
獲取元素CSS值之getComputedStyle方法熟悉
window.getComputedStyle方法雖然可以獲取到偽元素的屬性值,然而根據該方法名字也知道其只能獲取CSS樣式,并無法更改css屬性,那么如果想要用js動態更改偽元素屬性值的話,該怎么處理呢?
思路有以下幾個:
js更改data-*屬性值來更改偽元素的content值
創建多個class,通過切換class來達到改變樣式的目的
利用CSSStyleSheet的insertRule方法來添加樣式
利用內部css樣式的高優先級來覆蓋外部css
利用DOM的data-*屬性來更改content的值以上實現思路的推薦程度依次遞減
data-*是HTML5新增的DOM元素屬性,作用大致可以理解為標記。具體用法可以參考MDN的這篇文章.而偽元素的content屬性值除了常規賦值外,還有一種特殊的attr()方法來獲取。
HTML:
CSS:
.test::before{ content: attr(data-text); }
結果:
TEXT
另外content其實可以多個attr連寫,而且attr()內的可以是DOM元素的任意屬性(比如class等,甚至非W3C標準屬性也支持,不過不推薦這么做)所以很方便湊一些模版文字。像下面這種寫法也是完全沒問題的。注意用空格連接,不要用"+"號。
EXAM:
.test::before { content: "我的類是" attr(class) "想要變成" attr(data-color); }
雖然W3C給attr()賦予了無限可能性,包括color,width等屬性在未來都有希望用這個方法更改,然而目前只有content支持該方法,其余的都還是草稿狀態,尚未有瀏覽器支持。之所以把這個方法放在第一位只是因為相比別的實現手法來說,這個方法真的太簡單太優雅。
但是如果真的想要改偽元素里的color等元素呢?
更改class來實現偽元素樣式的更改把這個方法放到推薦位第二位估計會被很多人罵我:“臥槽,這么簡單又沒逼格的辦法你竟然放到第二位!太沒水平了”。不過再看完后面兩種方法后或許你會對這種看法有所改觀。
這個方法的優點是簡單好用且無兼容性問題。缺點是多了一些其實用處不大的class,很像是jQuery類選擇器中毒患者的做法;另外不適合多狀態的場景(比如實時改變偽元素文字大小等)。
實現過于簡單就不貼代碼了。
前面的class切換大法可能讓人感覺不痛快,這里來個高大上(偽)點的方法:
利用CSSStyleSheet的insertRule方法來添加樣式這部分內容和W3C標準牽連比較多,加上較冷門,沒多少人關注,個人目前啃不動標準,所以這部分內容不會做深入分析,理解可能也會有問題,望斧正。
CSSStyleSheet是瀏覽器存放頁面內所有css樣式表的對象方法(不包括行內樣式),每個link和style標簽都代表一個CSSStyleSheet對象,獲取他們可以用document.styleSheets方法。(需要注意的是雖然styleSheets方法返回的結果把link標簽引進的外部樣式也算進去了,但是非IE瀏覽器沒辦法獲取到他們的cssRules屬性,只有內嵌的style標簽內的元素可以被獲取到)
document.styleSheets[0].insertRule(".test::before{color:green}",0)//chrome,firefox等非IE瀏覽器使用 document.styleSheets[0].addRule(".test::before{color:green}",0)//IE系列瀏覽器使用 /* 雖然部分瀏覽器也可以通過id來指定,"document.styleSheets.id.insertRule()"這種寫法在chrome和IE下都行得通,但是firefox會返回"undefined",所以建議還是使用index值來獲取stylesheet */
.insertRule的語法是stylesheet.insertRule(rule, index),另一個參數是index,意思是在對應的styleSheets里的cssRules樣式表中的位置,這個值越大則樣式優先級越高,但是值不能超過當前樣式表規則(cssRules)長度(CSS中先定義的樣式總是會被后定義的覆蓋就是這個緣故。),當值小于cssRules長度時,添加的樣式規則會插入到index值定義的位置,之前其余的規則依次順延。
addrule和insertRule方法本質上沒區別,只是后者不被IE瀏覽器識別,所以前者作為瀏覽器兼容方法存在。(下文為節省篇幅,以insertRule方法指代此兩種方法。)
上面的代碼看似簡單一行,然而卻不是每次都有效的。原因有以下幾點:
document.styleSheets雖然按照style和link的順序返回對應的StyleSheetList,然而第一個如果是link而不是style,前面講過此時無法獲取對應的cssRules,則document.styleSheets[0].cssRules為null,insertRule方法不起作用。(此情況只針對非IE瀏覽器,IE瀏覽器正常,但是定義的早往往意味著被后面的樣式覆蓋,所以意義不大)
同上,如果頁面內沒有內嵌樣式的style標簽,則insertRule方法也無法發揮作用。
index值不夠大的話很有可能會早于css文件開始的定義位置,導致被覆蓋。因此有個折衷辦法就是給添加的樣式增加!important,雖然我個人比較反感這么做。
由此可見此方法的局限性,但是這種方法的優雅之處在于避免了直接寫內嵌樣式,而是通過css api來做更改。相比下面的方法來說,稍微好點。
但是這種方法好像局限性有點大???
HEAD中添加style標簽強制覆蓋初始屬性這個方法是利用內部css樣式的高優先級來覆蓋外部css,好處是簡單易理解,實現簡單。壞處就是吃相太難看,過于粗暴。
var style=document.createElement("style"); style.innerHTML=".test::before{color:green}";//添加樣式內容的話也可以用上面提到過的`insertRule`,相對例子里的硬編碼會更優雅點。 document.head.appendChild(style);
看到這里可能有些人反應過來了,其實加style標簽這種方法可以是insertRule實現方法的大前提——因為不是所有頁面一開始都有內嵌的style樣式的。這種方法雖然不是很好,但是有時候卻又確確實實是必須的——比如“拖動滑塊改變偽元素內文字大小”這個需求。
練習 功能需求拖動滑塊改變偽元素內的文字大小
且偽元素內隨時顯示當前字號
通過一個按鈕可以改變偽元素內文字顏色
這個需求可以將本文前面提到的四種改變偽元素樣式的方法都塞進去。具體實現參照DEMO,不再做具體分析:
http://codepen.io/chitanda/pen/OVBJEw/
參考文獻
getComputedStyle()
Window.getComputedStyle()
獲取元素CSS值之getComputedStyle方法熟悉
attr-notation
W3C CSS3-Attribute References: ‘attr()’
MDN ATTR()
CSSRules
CSSRule object
MDN insertRule
Dynamic style - manipulating CSS with JavaScript
Add Rules to Stylesheets with JavaScript
Modify pseudo element styles with JavaScript
Add css-rules to an existing stylesheet
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91525.html
摘要:標簽寫在后與前有什么區別什么是預處理器后處理器預處理器例如,用來預編譯或,增強了代碼的復用性,還有層級變量循環函數等,具有很方便的組件模塊化開發能力,極大的提高工作效率。 前言 因為面試的原因,最近又開始關注前端面試題,瀏覽過網上很多面試題集合,有很多小伙伴整理的很全面,但是我發現其中有很多技術點在當下已不再流行,而面試題一般都是映射開發中常遇到的一些技能和問題,再結合最近面試中遇到的...
閱讀 2065·2021-11-23 09:51
閱讀 2209·2021-09-29 09:34
閱讀 3701·2021-09-22 15:50
閱讀 3560·2021-09-22 15:23
閱讀 2577·2019-08-30 15:55
閱讀 705·2019-08-30 15:53
閱讀 3073·2019-08-29 17:09
閱讀 2630·2019-08-29 13:57