[javascript][翻譯]使用javascript添加css rule

  來杭一週,收穫不少,成長不少。javascript

  週六在搞一個插件的時候碰到須要動態添加僞元素的需求,搜了一下解決方案,有人用正則寫出了讀取僞元素的函數;我以爲卻是能夠經過注入css rule的方式,來讓預留有某些類的標籤動態產生僞元素。css

  而後在google上搜到這樣一篇文章,講了一下以前沒了解到的api函數:addrule等,翻譯一下,分享一下好了。html

  原博文網址:http://davidwalsh.name/add-rules-stylesheetsjava

 

譯文以下:web

 

  由於咱們在開發中javascript使用的愈來愈多,因此咱們老是想盡辦法想讓它更快。咱們使用事件代理來監聽事件,使用函數節流來限制單位時間內函數的調用次數,使用loader方法來加載最須要的資源。這些方法均可以讓咱們的頁面加載、渲染、執行的速度有必定的加快。本文要說另外一種方法:經過動態添加刪除CSS樣式代替原有的查找節點並修改來應用某些樣式。chrome

  • 獲取樣式表 

  咱們能夠選擇向頁面內的某條stylesheet中添加樣式。能夠給<link>標籤或者<style>標籤添加ID,經過引用節點的sheet屬性來獲取CSSStyleSheet對象。頁面中的stylesheets可使用document.styleSheets來獲取:api

var sheets = document.styleSheets; 
// returns an Array-like StyleSheetList
//返回一個類數組對象

/*
Returns:  

StyleSheetList {0: CSSStyleSheet, 1: CSSStyleSheet, 2: CSSStyleSheet, 3: CSSStyleSheet, 4: CSSStyleSheet, 5: CSSStyleSheet, 6: CSSStyleSheet, 7: CSSStyleSheet, 8: CSSStyleSheet, 9: CSSStyleSheet, 10: CSSStyleSheet, 11: CSSStyleSheet, 12: CSSStyleSheet, 13: CSSStyleSheet, 14: CSSStyleSheet, 15: CSSStyleSheet, length: 16, item: function}
*/

// Grab the first sheet, regardless of media
//先無論第一個樣式的具體應用media(注:多是print等)
var sheet = document.styleSheets[0];

  在咱們選取link或者style標籤時,咱們應該考慮被選中的樣式表標籤是不是應用於screen,而不是print等。CSSStyleSheet對象給咱們提供了這樣的屬性:數組

// Get info about the first stylesheet
console.log(document.styleSheets[0]);

/*
Returns:  

CSSStyleSheet
    cssRules: CSSRuleList
    disabled: false
    href: "http://davidwalsh.name/somesheet.css"
    media: MediaList
    ownerNode: link
    ownerRule: null
    parentStyleSheet: null
    rules: CSSRuleList
    title: null
    type: "text/css"
*/

// Get the media type
//獲取media類型
console.log(document.styleSheets[0].media.mediaText)
/*
Returns:
    "all" or "print" or whichever media is used for this stylesheet
*/

  固然除了上面的,還有別的方法能夠獲取stylesheet對象。瀏覽器

  

  • 建立新樣式表

  有些狀況下,可能新建一個style節點來承裝新添加的style rule。方法很簡單:app

var sheet = (function() {
    // Create the <style> tag
    var style = document.createElement("style");

    // Add a media (and/or media query) here if you'd like!
    // style.setAttribute("media", "screen")
    // style.setAttribute("media", "only screen and (max-width : 1024px)")

    // WebKit hack :(
        //webkit內核瀏覽器的hack:
    style.appendChild(document.createTextNode(""));

    // Add the <style> element to the page  插入頁面
    document.head.appendChild(style);

    return style.sheet;
})();    

  請留意上面第三條語句是爲webkit瀏覽器添加的hack。

  

  • 插入規則  insertRule(styles,[index])

  Stylesheets對象提供了insertRule(譯者注:IE8及如下不兼容,具體參考連接http://www.quirksmode.org/dom/w3c_css.html )方法。insertRule函數要求傳入css樣式風格的str做爲參數。

  具體調用方法:

sheet.insertRule("header { float: left; opacity: 0.8; }", 1);

  (譯者注:傳入的樣式str的格式要求不少。就我目前發現的:1.{}兩個花括號和先後最好都有一個空格 2.若是是webkit內核,函數在解析帶有-moz-前綴的樣式規則時會拋err)

  這種方法看上去有點醜,可是確實有用。第二個參數Index,表示咱們將在樣式內部的哪一條插入新樣式css rule,這就能夠幫助咱們實現原有樣式的覆蓋。默認index取值是-1(譯者注:可是輸入-1在chrome 41下拋了err,提示參數不能小於0,這裏值得在研究一下),表示默認在樣式最後追加。若是想強制覆蓋,可使用!important,來避免插入次序引發其餘問題。

 

  • 添加規則(非標準函數)  addRule(selector,styles,index)

  CSSStyleSheet對象有一個非標準函數addRule,和insertRule相比,它更像js api的調用風格,無需本身注意插入的樣式字符串的格式。addRule方法接受三個參數,分別是選擇器selector,樣式字符串"color:red;font-size:12px",和插入次序index。

sheet.addRule("#myList li", "float: left; background: red !important;", 1);

  方法有返回值,爲-1。可是沒有什麼具體含義。

  這種方式能夠快速高效的改變頁面上節點的已有樣式。

  

  • 應用樣式

  由於上面提到兩個函數都不是常見api函數,因此須要作瀏覽器兼容性處理。

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);
    }
}

// Use it!
addCSSRule(document.styleSheets[0], "header", "float: left");

  這種方法能夠應用於全部高級的瀏覽器,若是仍是有擔憂的話,能夠在調用時使用try-catch結構。

 

  • 爲Media queries插入樣式規則

  若是你須要插入media-queries的css樣式規則,你只能使用第一個insertRule方法。

sheet.insertRule("@media only screen and (max-width : 1140px) { header { display: none; } }");

  IE不支持insertRule函數,因此另外一種方法是建立style標籤節點,經過寫入的方式來注入樣式規則。

 

  動態添加樣式規則是有效且容易的。在下一個應用裏嘗試一下吧,你會發現這個真的很好用~

 

譯文結束

相關文章
相關標籤/搜索