前言:這是筆者學習之后自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新!
引入CSS有3種方式:行間樣式,內聯樣式和外部鏈接樣式。
在實際工作中,我們使用 javascript 操作CSS樣式時:
- 在改變元素的單個樣式時,一般會直接操作,改變其行間樣式;如:obj.style.color=...
- 同時改變元素的較多樣式時,可以使用 cssText,改變其行間樣式;obj.style.cssText=...
- 更常用的是使用 css 類,將更改前和更改后的樣式提前設置為類 。只要更改其類名 className 即可,obj.className;
- 如果要改變多個類名,使用 classList 更為方便,IE9及以下瀏覽器不支持;
行間樣式
行間樣式又叫內聯樣式,element 元素節點提供 style 屬性,用來操作 CSS 行間樣式;
如果一個 CSS 屬性名包含一個或多個連字符,屬性名的格式應該是移除連字符,將每個連字符后面緊接着的字母大寫(駝峰命名法);
<div class="wrapper" style="width: 500px;height: 200px;border-bottom: 10px solid #ff0;"></div> <script type="text/javascript"> var oWrapper = document.getElementsByClassName('wrapper')[0]; console.log(oWrapper.style.borderBottom);//10px solid rgb(255, 255, 0) </script>
其實,如果操作行間樣式,可以使用元素節點的屬性操作方法 hasAttribute()、getAttribute()、setAttribute()、removeAttribute() 等,來操作style屬性;
<div class="wrapper" style="width: 500px;height: 200px;border-bottom: 10px solid #ff0;"></div> <script type="text/javascript"> var oWrapper = document.getElementsByClassName('wrapper')[0]; oWrapper.setAttribute('style','background-color: #0ff;') //setAttribute 設置的是當前屬性的整體 console.log(oWrapper.hasAttribute('style'));//true console.log(oWrapper.getAttribute('style'));//background-color: #0ff; </script>
cssText
通過 cssText 屬性能夠訪問到 style 屬性中的CSS代碼(行間樣式);
在讀模式下,cssText 返回瀏覽器對 style 屬性中的CSS代碼的內部表示;IE8及以下瀏覽器返回的屬性名是全大寫的
在寫模式中,賦給 cssText 的值會重寫整個 style 屬性的值;
<div class="wrapper" style="width: 500px;height: 200px;border-bottom: 10px solid #ff0;"></div> <script type="text/javascript"> var oWrapper = document.getElementsByClassName('wrapper')[0]; console.log(oWrapper.style.cssText); //width: 500px; height: 200px; border-bottom: 10px solid rgb(255, 255, 0); oWrapper.style.cssText = 'background-color: #0ff;'; console.log(oWrapper.style.cssText);//background-color: rgb(0, 255, 255); </script>
length
length 屬性返回內聯樣式中的樣式個數;IE8及以下瀏覽器不支持;
<div class="wrapper" style="width: 500px;height: 200px;border-bottom: 10px solid #ff0;"></div> <script type="text/javascript"> var oWrapper = document.getElementsByClassName('wrapper')[0]; console.log(oWrapper.style.length);//5 //width height border-bottom-width border-bottom-style border-bottom-color </script>
方法
getPropertyPriority(propertyName) 如果給定的屬性使用了!important設置,則返回"important";否則返回空字符串;IE8及以下瀏覽器不支持
setProperty(propertyName,value,priority) 方法將給定屬性設置為相應的值,並加上優先級標志("important"或一個空字符串),該方法無返回值;IE8及以下瀏覽器不支持
removeProperty(propertyName) 方法從樣式中刪除給定屬性,並返回被刪除屬性的屬性值;IE8及以下瀏覽器不支持
<div id="test" style="height: 40px!important;width: 40px;background-color: pink;border:10px solid #f0f"></div> <script> var oTest = document.getElementById('test'); //getPropertyPriority() 如果給定的屬性使用了!important設置,則返回"important";否則返回空字符串 console.log(oTest.style.getPropertyPriority('height'));//'important' console.log(oTest.style.getPropertyPriority('width'));//'' //setProperty(propertyName,value,priority)方法將給定屬性設置為相應的值,並加上優先級標志("important"或一個空字符串) oTest.style.setProperty('width','100px'); console.log(oTest.style.width);//100px console.log(oTest.style.getPropertyPriority('width'));//'' oTest.style.setProperty('background-color','blue','important'); console.log(oTest.style.backgroundColor);//blue console.log(oTest.style.getPropertyPriority('background-color'));//important //removeProperty()方法從樣式中刪除給定屬性,並返回被刪除屬性的屬性值 console.log(oTest.style.border);//10px solid rgb(255, 0, 255) oTest.style.removeProperty('border'); console.log(oTest.style.border);//'' </script>
計算樣式
元素的渲染結果是多個CSS樣式博弈后的最終結果,這也是CSS中的C(cascade)層疊的含義。cssText 只能獲取行間樣式,這通常來說,並不是我們想要的結果,我們有時候需要的是元素的計算樣式(無論行內、內聯或鏈接);
元素的計算樣式(computedStyle)是一組在顯示元素時實際使用的屬性值,也是用一個 CSSStyleDeclaration 對象來表示的,但實際樣式是只讀的,主要通過getComputedStyle() 方法實現;IE8及以下瀏覽器不支持
getComputedStyle() 方法接收兩個參數:要取得計算樣式的元素和一個偽元素字符串。如果不需要偽元素信息,第二個參數可以是 null。getComputedStyle() 方法返回一個 CSSStyleDeclaration 對象,其中包含當前元素的所有計算的樣式;
第二個參數代表偽元素字符串,包括":before"、":after"、":first-line"等,如果設置為null或省略不寫,則返回自身元素的 CSSStyleDeclaration 對象;
對於font、background、border等復合樣式,各瀏覽器處理不一樣。chrome 會返回整個復合樣式,而IE9+、firefox和safari則輸出空字符串'';
在計算樣式中,類似百分比等相對單位會轉換為絕對值;
<style type="text/css"> #test{ background-color: #ff0; } #test:before{ content: ""; width: 50px; display: block; } </style> <div id="test" style="width: 100px;height: 200px;"></div> <script type="text/javascript"> var oTest = document.getElementById('test'); console.log(getComputedStyle(oTest).width);//100px console.log(getComputedStyle(oTest).height);//200px console.log(getComputedStyle(oTest).backgroundColor);//rgb(255, 255, 0) console.log(getComputedStyle(oTest,':before').width);//50px </script>
IE8及以下瀏覽器不支持 getComputedStyle() 方法,但在 IE 中每個具有 style 屬性的元素有一個 currentStyle 屬性,這個屬性是 CSSStyleDeclaration 的實例,包含當前元素全部計算后的樣式;
obj.currentStyle[style] 屬性中的計算樣式並不會輸出集合樣式,對顏色、百分比設置不會進行相應轉換,而是原樣輸出;
<style type="text/css"> #test{ background-color: #ff0; } </style> <div id="test" style="width: 30%;height: 200px;"></div> <script type="text/javascript"> var oTest = document.getElementById('test'); //標准瀏覽器會報錯,IE正常顯示 console.log(oTest.currentStyle.backgroundColor);//#ff0 console.log(oTest.currentStyle.width);//30% console.log(oTest.currentStyle.height);//200px </script>
兼容性寫法
<style type="text/css"> #test{ background-color: #ff0; } </style><div id="test" style="width: 30%;height: 200px;"></div> <script type="text/javascript"> function getCSS(obj,attribute){ return window.getComputedStyle ? getComputedStyle(obj)[attribute] : obj.currentStyle[attribute]; } var oTest = document.getElementById('test'); console.log(getCSS(oTest,'width'));//計算出來的絕對值 console.log(getCSS(oTest,'height'));//200px </script>
動態樣式
動態樣式包括兩種情況:一種是通過<link>元素插入外部樣式表,另一種是通過<style>元素插入內部樣式。
<script type="text/javascript"> //動態加載外部樣式 function loadLinkCSS(urlData){ loadLinkCSS.mark = 'load';//標記是否執行過此程序 var linkCSS = document.createElement("link"); linkCSS.rel = "stylesheet"; linkCSS.type = "text/css"; linkCSS.href = urlData;//路徑設置 var oHead = document.getElementsByTagName('head')[0]; oHead.appendChild(linkCSS); } //動態加載內部樣式 //該方法在IE8及以下瀏覽器中報錯,因為IE8及以下瀏覽器將<style>視為當作特殊的節點,不允許訪問其子節點或設置 innerHTML 屬性 function loadStyleCSS(str){ loadStyleCSS.mark = 'load';//標記是否執行過此程序 var styleCSS = document.createElement("style"); styleCSS.type = "text/css"; styleCSS.innerHTML = str; var head = document.getElementsByTagName('head')[0]; head.appendChild(styleCSS); } </script>
動態插入內部樣式時,存在兼容問題,有兩種兼容處理辦法:
- IE瀏覽器支持訪問並修改元素的 CSSStyleSheet 對象的 cssText 屬性,通過修改該屬性可實現類似效果;
- 作用域元素是微軟自己的一個定義。在IE8及以下瀏覽器中,<style>元素是一個沒有作用域的元素,如果通過 innerHTML 插入的字符串開頭就是一個無作用域的元素,那么IE8及以下瀏覽器會在解析這個字符串前先刪除該元素;
<script type="text/javascript"> //動態加載內部樣式的兼容性寫法一 //IE瀏覽器支持訪問並修改元素的 CSSStyleSheet 對象的 cssText 屬性,通過修改該屬性可實現類似效果 function loadStyleCssCompatA(str){ loadStyleCssCompatA.mark = 'load';//標記是否執行過此程序 var styleCSS = document.createElement("style"); styleCSS.type = "text/css"; try{ styleCSS.innerHTML = str; }catch(ex){ styleCSS.styleSheet.cssText = str; } var head = document.getElementsByTagName('head')[0]; head.appendChild(styleCSS); } //動態加載內部樣式的兼容性寫法二 //在IE8及以下瀏覽器中,style元素是一個沒有作用域的元素, //如果通過 innerHTML 插入的字符串開頭就是一個無作用域的元素,那么IE8及以下瀏覽器會在解析這個字符串前先刪除該元素 function loadStyleCssCompatB(str){ loadStyleCssCompatB.mark = 'load'; var styleCSS = document.createElement("div"); styleCSS.innerHTML = '_' + '<style>' + str+'</style>'; styleCSS.removeChild(div.firstChild); var oHead = document.getElementsByTagName('head')[0]; oHead.appendChild(styleCSS.firstChild); styleCSS = null; } </script>
CSS模塊偵測
CSS的規則發展太快,新的模塊層出不窮。不同瀏覽器的不同版本,對CSS模塊的支持情況都不一樣。有時候,需要知道當前瀏覽器是否支持某個模塊,這就叫做"CSS模塊的偵測";
一個比較普遍適用的方法是,判斷某個DOM元素的 style 對象的某個屬性值是否為字符串。如果該CSS屬性確實存在,會返回一個字符串。即使該屬性實際上並未設置,也會返回一個空字符串。如果該屬性不存在,則會返回 undefined
CSS.supports() 方法返回一個布爾值,表示是否支持某條CSS規則;safari 和 IE瀏覽器不支持
<div id="test"></div> <script> var oTest = document.getElementById('test'); //CSS模塊的偵測 //IE9及以下瀏覽器和safari返回undefined,其他瀏覽器都返回'', //所以IE9及以下瀏覽器和safari不支持animation console.log(oTest.style.animation); //IE和firefox瀏覽器返回undefined,chrome和safari瀏覽器都返回'', //所以IE和firefox瀏覽器不支持WebkitAnimation console.log(oTest.style.WebkitAnimation); //safari和IE瀏覽器不支持, //chrome返回true console.log(CSS.supports('transition','1s'));//true </script>