Js判斷CSS檔案載入完畢的具體實現

來源:互聯網
上載者:User

 在多數情況下我們不需要判斷css檔案是否載入成功了,但有些時間這個功能還是需要的,今天我來整理了相容各種瀏覽器的判斷CSS檔案載入完畢實現方法與各位分享

要判斷這個 CSS 檔案是否載入完畢,各個瀏覽器的做法差異比較大,這次要說IE瀏覽器做的不錯,我們可以直接通過onload方法來處理CSS載入完成以後的處理: 代碼如下:// 代碼節選至seajsfunction styleOnload(node, callback) {    // for IE6-9 and Opera    if (node.attachEvent) {      node.attachEvent('onload', callback);      // NOTICE:      // 1. "onload" will be fired in IE6-9 when the file is 404, but in      // this situation, Opera does nothing, so fallback to timeout.      // 2. "onerror" doesn't fire in any browsers!    }}   很遺憾,這次在其他的瀏覽器中,想判斷CSS是否載入完成就不是那麼方便了,FF,webkit可以通過node.sheet.cssRules屬性是否存在來判斷是否載入完畢。而且需要使用setTimeout間隔事件輪詢:   代碼如下:// 代碼節選至seajs function poll(node, callback) {    if (callback.isCalled) {      return;    }    var isLoaded = false;    if (/webkit/i.test(navigator.userAgent)) {//webkit      if (node['sheet']) {        isLoaded = true;      }    }    // for Firefox    else if (node['sheet']) {      try {        if (node['sheet'].cssRules) {          isLoaded = true;        }      } catch (ex) {        // NS_ERROR_DOM_SECURITY_ERR        if (ex.code === 1000) {          isLoaded = true;        }      }    }    if (isLoaded) {      // give time to render.      setTimeout(function() {        callback();      }, 1);    }    else {      setTimeout(function() {        poll(node, callback);      }, 1);    }  }  setTimeout(function() {     poll(node, callback);}, 0);   SeaJS給出的完整的處理是這樣的:  代碼如下:function styleOnload(node, callback) {    // for IE6-9 and Opera    if (node.attachEvent) {      node.attachEvent('onload', callback);      // NOTICE:      // 1. "onload" will be fired in IE6-9 when the file is 404, but in      // this situation, Opera does nothing, so fallback to timeout.      // 2. "onerror" doesn't fire in any browsers!    }    // polling for Firefox, Chrome, Safari    else {      setTimeout(function() {        poll(node, callback);      }, 0); // for cache    }  }  function poll(node, callback) {    if (callback.isCalled) {      return;    }    var isLoaded = false;    if (/webkit/i.test(navigator.userAgent)) {//webkit      if (node['sheet']) {        isLoaded = true;      }    }    // for Firefox    else if (node['sheet']) {      try {        if (node['sheet'].cssRules) {          isLoaded = true;        }      } catch (ex) {        // NS_ERROR_DOM_SECURITY_ERR        if (ex.code === 1000) {          isLoaded = true;        }      }    }    if (isLoaded) {      // give time to render.      setTimeout(function() {        callback();      }, 1);    }    else {      setTimeout(function() {        poll(node, callback);      }, 1);    }  }// 我的動態建立LINK函數function createLink(cssURL,lnkId,charset,media){     var head = document.getElementsByTagName('head')[0],        linkTag = null;  if(!cssURL){     return false; }     linkTag = document.createElement('link'); linkTag.setAttribute('id',(lnkId || 'dynamic-style')); linkTag.setAttribute('rel','stylesheet'); linkTag.setAttribute('charset',(charset || 'utf-8')); linkTag.setAttribute('media',(media||'all')); linkTag.setAttribute('type','text/css');    linkTag.href = cssURL;      head.appendChild(linkTag); }function loadcss(){    var styleNode = createLink('/wp-content/themes/BlueNight/style.css');     styleOnload(styleNode,function(){        alert("loaded");    });} 在看到seajs的代碼的時候,我立刻想起了我看到Diego Perini的另一個解決方案:代碼如下:/* * Copyright (C) 2010 Diego Perini * All rights reserved. * * cssready.js - CSS loaded/ready state notification * * Author: Diego Perini <diego.perini at gmail com> * Version: 0.1 * Created: 20100616 * Release: 20101104 * * License: *  http://www.jb51.net * Download: *  http://javascript.nwbox.com/cssready/cssready.js */function cssReady(fn, link) {  var d = document,  t = d.createStyleSheet,  r = t ? 'rules' : 'cssRules',  s = t ? 'styleSheet' : 'sheet',  l = d.getElementsByTagName('link');  // passed link or last link node  link || (link = l[l.length - 1]);  function check() {    try {      return link && link[s] && link[s][r] && link[s][r][0];    } catch(e) {      return false;    }  }  (function poll() {    check() && setTimeout(fn, 0) || setTimeout(poll, 100);  })();}   其實,如果你讀過jQuery的domready事件的判斷的代碼,原理也類似。也是通過setTimeout輪詢的方式來判斷DOM節點是否載入完畢。還有,Fackbook則是通過在動態建立的CSS樣式中包含一個固定的樣式,例如#loadcssdom,loadcssdom就是一個高度為1px樣式。然後動態建立一個DOM對象,添加這個loadcssdom樣式。然後也是setTimeout輪詢loadcssdo是否已經有1px的高度了。這個處理方式的解決方案,大家可以下《CSSP: Loading CSS with Javascript – and getting an onload callback.》而《JavaScript Patterns》的作者Stoyan則在他的部落格裡,比較詳細的說明了《When is a stylesheet really loaded?》。看完了這些,你可能會感歎:汗,判斷CSS是否載入完畢,目前還真不是那麼容易!其實我這裡算是一個拋磚引玉,因為開發中,除了動態載入CSS,我們還要動態載入JavaScript,動態載入HTML的操作,有空我也會寫關於動態載入JavaScript的相關內容,不過在那之前,我建議你看看這些:    《ensure – Ensure JavaScripts/HTML/CSS are loaded on-demand when needed》,這個庫是專門處理動態載入HTML,CSS,JavaScript的。就像作者介紹的那樣:        ensure is a tiny JavaScript library that provides a handy function ensure which allows you to load JavaScript, HTML, CSS on-demand, and then execute your code. ensure www.jb51.net ensures that the relevant JavaScript and HTML snippets are already in the browser DOM before executing your code that uses them.    《Tell CSS that JavaScript is available ASAP》    看完這個後,你可能就不會糾結:When you're styling parts of a web page that will look and work differently depending on whether JavaScript is available or not。好了,這次就說這麼多了,希望對對大家的開發和學習有協助! 
相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。