JavaScript實現(xiàn)動態(tài)創(chuàng)建CSS樣式規(guī)則方案
現(xiàn)在Web應用中有大量的JavaScript代碼,而我們也一直在追尋各種使他們更快的解決方案。
1.我們通過 事件代理(event delegation) 讓事件監(jiān)聽更高效,
2.我們利用 函數(shù)降頻技術(function debouncing) 來限制一段時間內給定方法被調用的次數(shù),請參考:如何防止事件函數(shù)的高頻觸發(fā)(中文翻譯)
3.我們使用 JavaScript加載器 來加載我們確實需要的那部分資源,等等。
還有一種方式,可以讓我們的頁面更加的快速和高效.那就是直接通過JS動態(tài)地添加和刪除樣式表中的某些樣式,用來取代不斷地查詢DOM元素,并應用各種樣式。下面是它的工作原理。
獲取樣式表
你可以選擇任意的樣式表來添加樣式規(guī)則。如果你有確定的樣式表,則可以在HTML頁面中給 <link> 或 <style> 標簽添加ID屬性,然后直接通過這個DOM元素的 sheet 屬性就可以取得 CSSStyleSheet 對象。樣式表也可以通過 document.styleSheets 遍歷到:
// 返回一個類似數(shù)組的(Array-like)樣式列表 StyleSheetList
var sheets = document.styleSheets;
/*
返回值類似下面這樣:
StyleSheetList
{
0: CSSStyleSheet,
1: CSSStyleSheet,
2: CSSStyleSheet,
3: CSSStyleSheet,
4: CSSStyleSheet,
length: 5,
item: function
}
*/
// 獲取第一個sheet, 先不管 media屬性
var sheet = document.styleSheets[0];
需要特別注意的是樣式表的media屬性 —— 當你想在屏幕上顯示的時候,你肯定不能把CSS規(guī)則加到打印樣式表中。你可以仔細的看一下CSSStyleSheet對象的屬性信息:
// 控制臺輸出第一個樣式表的信息
console.log(document.styleSheets[0]);
/*
返回值:
CSSStyleSheet
cssRules: CSSRuleList[對象]
disabled: false
href: "
media: MediaList[對象]
ownerNode: link[對象]
ownerRule: null
parentStyleSheet: null
rules: CSSRuleList[對象]
title: null
type: "text/css"
*/
// 獲取媒體類型(media type)
console.log(document.styleSheets[0].media.mediaText)
/*
返回值可能是:
"all" 或者 "print" 或者是其他應用到此樣式表的 media
*/
在各種情況下,你肯定都有辦法來獲取到要添加規(guī)則的樣式表。
創(chuàng)建一個新樣式表
在許多情況下,最好的方法可能是創(chuàng)建一個新的 <style> 元素來存放這些動態(tài)規(guī)則。這也很簡單:
var sheet = (function() {
// 創(chuàng)建 <style> 標簽
var style = document.createElement("style");
// 可以添加一個媒體(/媒體查詢,media query)屬性
// style.setAttribute("media", "screen")
// style.setAttribute("media", "only screen and (max-width : 1024px)")
// 對WebKit hack :(
style.appendChild(document.createTextNode(""));
// 將 <style> 元素加到頁面中
document.head.appendChild(style);
return style.sheet;
})();
悲劇的是WebKit需要一點hack手段才能正確創(chuàng)建,但我們只需要關心這個sheet。
插入規(guī)則
在早期版本的IE中 Stylesheets 的 insertRule方法并不可用,雖然現(xiàn)在這是規(guī)則注入的標準。insertRule 方法需要編寫整個CSS規(guī)則,和在樣式表中是一樣的寫法:
sheet.insertRule("header { float: left; opacity: 0.8; }", 1);
這個JavaScript API方法雖然看起來有點土,但它確實就是這樣運行的。第二個參數(shù) index 表示要插入規(guī)則的位置(索引)。這也是非常有用的,這樣你就可以插入同樣的規(guī)則/代碼,這可以讓靠后的規(guī)則生效。默認的index是 -1 ,代表整個集合的末尾。如果想要有額外的/懶惰控制規(guī)則,你也可以添加 !important 標記到某條規(guī)則后,以避免索引的問題。
添加規(guī)則 —— 非標準的 addRule 方法
CSSStyleSheet 對象有一個 addRule 方法,允許你注冊CSS規(guī)則到樣式表中。 addRule 方法接受三個參數(shù): 第一個參數(shù)是選擇器(selector)、第二個參數(shù)是CSS規(guī)則代碼, 第三個則是從0開始的整數(shù)索引,表示樣式的位置(在同一個選擇器中):
sheet.addRule("#myList li", "float: left; background: red !important;", 1);
addRule方法的返回值總是 -1,所以這個值并沒有什么實際意義.
記住,這種方式的優(yōu)點在于,從頁面添加的元素自動擁有了應用于他們的樣式,也就是說你不必將它們添加到具體的元素上,而是直接注入到頁面中。當然效率更高!
安全應用規(guī)則
因為并不是所有的瀏覽器都支持 insertRule 方法, 所以最好創(chuàng)建一個包裝函數(shù)來處理規(guī)則應用。下面是一個快速的土方法:
function addCSSRule(sheet, selector, rules, index) {
if("insertRule" in sheet) {
sheet.insertRule(selector + "{" + rules + "}", index);
}
else if("addRule" in sheet) {
sheet.addRule(selector, rules, index);
}
}
// 使用方式
addCSSRule(document.styleSheets[0], "header", "float: left");
這個工具方法應該涵蓋了新增style規(guī)則的所有情況。如果你擔心在應用中出錯, 那么應該將該方法的代碼用一個 try{} catch(e){} 塊包起來。
插入媒體查詢規(guī)則
媒體查詢規(guī)則的添加有兩種方式。第一個是使用標準 insertRule 方法:
sheet.insertRule(
"@media only screen and (max-width : 1140px) { header { display: none; } }"
);
當然,因為IE老版本不支持 insertRule,所以另一種方法就是創(chuàng)建一個 STYLE 元素,并指定適當?shù)?media 屬性,然后將樣式添加到新的樣式表中。這可能需要使用多個 STYLE 元素,但也是很容易的。我可能會創(chuàng)建一個對象,指定媒體查詢以及索引,并那樣創(chuàng)建/獲取他們。
動態(tài)添加規(guī)則到樣式表是高效的手段,可能比你想象的還要簡單。請記住這種方案,可能在你的下一個大應用中需要使用,因為它能在代碼和元素處理這兩方面避免你掉進坑里。
- JavaScript動態(tài)創(chuàng)建div屬性和樣式示例代碼
- javascript 動態(tài)創(chuàng)建表格
- javascript動態(tài)創(chuàng)建及刪除元素的方法
- JavaScript動態(tài)創(chuàng)建link標簽到head里的方法
- JavaScript與DOM組合動態(tài)創(chuàng)建表格實例
- javascript轉換字符串為dom對象(字符串動態(tài)創(chuàng)建dom)
- javascript 翻頁測試頁(動態(tài)創(chuàng)建標簽并自動翻頁)
- JavaScript 動態(tài)創(chuàng)建VML的方法
- Javascript動態(tài)創(chuàng)建div的方法
- javascript 動態(tài)創(chuàng)建 Option選項
相關文章
javascript數(shù)組對象常用api函數(shù)小結(連接,插入,刪除,反轉,排序等)
這篇文章主要介紹了javascript數(shù)組對象常用api函數(shù),結合實例形式總結分析了javascript針對數(shù)組的連接、刪除、反轉、排序、插入等操作相關函數(shù)用法,需要的朋友可以參考下2016-09-09JavaScript使用delete刪除數(shù)組元素用法示例【數(shù)組長度不變】
這篇文章主要介紹了JavaScript使用delete刪除數(shù)組元素用法,結合實例形式分析了delete刪除數(shù)組元素的具體用法與注意事項,需要的朋友可以參考下2017-01-01使用JavaScript實現(xiàn)Java的List功能(實例講解)
使用JavaScript實現(xiàn)Java的List功能(實例講解)。需要的朋友可以過來參考下,希望對大家有所幫助2013-11-11利用原生JS與jQuery實現(xiàn)數(shù)字線性變化的動畫
最近在工作中遇到一個需要,需要將數(shù)字實現(xiàn)遞增的動態(tài)顯示,從網上找了相關的資料發(fā)現(xiàn)利用原生JS與jQuery都可以實現(xiàn),suoyi8下面這篇文章主要給大家介紹了利用原生JS與jQuery實現(xiàn)數(shù)字線性變化動畫的相關資料,需要的朋友可以參考下。2017-02-02