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

來源:互聯網
上載者:User

標籤:

  來杭一周,收穫很多,成長很多。

  周六在搞一個外掛程式的時候碰到需要動態添加虛擬元素的需求,搜了一下解決方案,有人用正則寫出了讀取虛擬元素的函數;我覺得倒是可以通過注入css rule的方式,來讓預留有某些類的標籤動態產生虛擬元素。

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

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

 

譯文如下:

 

  因為我們在開發中javascript使用的越來越多,所以我們總是想盡辦法想讓它更快。我們使用事件代理來監聽事件,使用函數節流來限制單位時間內函數的調用次數,使用loader方法來載入最需要的資源。這些方法都可以讓我們的頁面載入、渲染、執行的速度有一定的加快。本文要說另一種方法:通過動態添加刪除CSS樣式代替原有的尋找節點並修改來應用某些樣式。

  • 擷取樣式表 

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

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 stylesheetconsole.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。方法很簡單:

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標籤節點,通過寫入的方式來注入樣式規則。

 

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

 

譯文結束

 

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

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.