繁体   English   中英

如何检查是否使用Javascript加载外部(跨域)CSS文件

[英]HOW TO check if an external (cross-domain) CSS file is loaded using Javascript

我有一个函数使用javascript执行以下操作:

  1. 创建link元素并设置href = cssFile。
  2. 在head标签中插入link元素。
  3. 创建一个div元素。
  4. 使用setAttribute设置类名
  5. appendChild身体上的div。
  6. 现在使用document.defaultView.getComputedStyle(divElement, null)[cssRule]获取CSS规则值。

现在getComputedStyle返回默认值,如果我在getComputedStyle调用之前使用Firebug等待断点 ,那么它将从注入的CSS返回CSS规则。

问候,
穆奈姆

您可以使用普通的ajax调用创建动态css url并将css作为纯文本获取。

然后使用它来加载css:

function loadCss(cssText, callback){
    var style = document.createElement('style');
    style.type='text/css';
    if(callBack != undefined){
        style.onload = function(){
            callBack();
        };
    }
    style.innerHTML = cssText;
    head.appendChild(style);
}

并像这样使用它:

loadCss(ajaxResponseText, function(){
    console.log("yaay css loaded, now i can access css defs");
})

这实际上就是我做的。

为了确保加载特定的CSS文件,我在CSS文件的末尾添加了一个样式。 例如:

#ensure-cssload-8473649 {
  display: none
}

现在我有一个JavaScript函数,它将触发在页面上加载上述样式时指定的回调:

var onCssLoad = function (options, callback) {
    var body = $("body");
    var div = document.createElement(constants.TAG_DIV);
    for (var key in options) {
        if (options.hasOwnProperty(key)) {
            if (key.toLowerCase() === "css") {
                continue;
            }
            div[key] = options[key];
        }
    }

    var css = options.css;
    if (css) {
        body.appendChild(div);
        var handle = -1;
        handle = window.setInterval(function () {
            var match = true;
            for (var key in css) {
                if (css.hasOwnProperty(key)) {
                    match = match && utils.getStyle(div, key) === css[key];
                }
            }

            if (match === true) {
                window.clearTimeout(handle);
                body.removeChild(div);
                callback();
            }
        }, 100);
    }
}

这就是我使用上述功能的方式:

onCssLoad({
    "id": "ensure-cssload-8473649",
    css: {
        display: "none"
    }
}, function () {
    // code when you want to execute 
    // after your CSS file is loaded
});

这里的第一个参数采用id来检查测试样式和css属性的options ,以验证从CSS加载的内容。

我假设你这样做是因为你需要动态创建样式表的URL。

想到几个选项:

1)创建URL服务器端并完全避免此问题。

2)使用setTimeout检查样式是否已加载并每隔20ms检查一次,直到getComputedStyle返回所需的值。

我根本不喜欢#2 ......但这是一个选择。 如果使用#2,请确保即使存在异常也要清除超时。

这是一个似乎适用于所有浏览器的解决方案。

function loadCss(fileUrl) {
  // check for css file type
  if (fileUrl.indexOf(".css")==fileUrl.length-4) {
    // Create link element
    var fileref=document.createElement("link");
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", fileUrl);
    if (typeof fileref!="undefined") {
      // remove the . if this is a relative link
      if(fileUrl.indexOf('.')==0) {
        fileUrl = fileUrl.substr(1);
  }
  // generate the full URL to use as the fileId
      var pathname = window.location.pathname;
  var pathUrl = pathname.substr(0,pathname.lastIndexOf("/"));
  var fileId = window.location.protocol + "//" + window.location.host + pathUrl + fileUrl;
      // append the newly created link tag to the head of the document
      document.getElementsByTagName("head")[0].appendChild(fileref);

  // begin checking for completion (100ms intervals up to 2000ms)
  this.checkCSSLoaded(fileId,100,0,2000);

    } else throw 'INVALID_CSS_ERROR';
  } else throw 'INVALID_CSS_ERROR';
}

function checkCSSLoaded(cssHref,milliPerCheck,milliPerCount,milliTimeout) {
  // Look through all sheets and try to find the cssHref
  var atSheet = -1;
  var sheetLength = document.styleSheets.length;
  while(++atSheet < sheetLength ) {
if(cssHref == document.styleSheets[atSheet].href) {
      // If found dispatch and event or call a procedure
      /* Do whatever is next in your code here */
  return;
}
  }
  // check for timeout
  if(milliCount > milliTimeout) { 
    alert('INVALID_CSS_ERROR::'+" ("+cssHref+"+ not found!");
    /* Do whatever happens if timeout is reached here */
return;
  }
  // else keep trying
  setTimeout(checkCSSLoaded ,milliPerCheck, cssHref, milliPerCheck, milliCount+millPerCheck, milliTimeout);
}

基本上我们

  1. 创建链接标记。
  2. 设置其属性,使其知道样式表链接标记
  3. 以这样的方式创建文件ID,使其始终为完整文件URL
  4. 将链接标记附加到文档头的头部
  5. 执行连续测试以查看(stylesheet.href == fileID)是否存在
    • 如果发现其他事情,如果超时做其他事情继续检查

使用document.styleSheets检查是否加载了css是错误的,因为只要将css链接添加到DOM,它就可以从document.styleSheets获得,即使它尚未加载。

向CSS添加标记也很麻烦。

正确的解决方案是收听onload事件:

   var loadedCss = {};
   cssHref = "http://www.foo.com/bar.css";
   css = document.createElement("link");
   css.setAttribute("rel", "stylesheet");
   css.setAttribute("type", "text/css");
   css.setAttribute("href", cssHref);
   css.onload = function(){
      loadedCss[cssHref] = true;
   }
   document.getElementsByTagName("head")[0].appendChild(css);


   function isCssLoaded(url) {
       return loadCss[url];
   }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM