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

IT技术 javascript css
2021-02-24 10:30:41

我有一个使用以下功能执行以下操作的函数javascript

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

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

问候,
穆尼姆

5个回答

您可以创建动态 css url 并使用普通的 ajax 调用以纯文本形式获取 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");
})
应该是style.onload = callback;(另外,请注意大小写)。
2021-04-27 10:30:41
+1 此解决方案。我更喜欢它而不是我提出的,假设所有浏览器都可以解释动态添加的样式标签(还没有尝试过)。
2021-04-29 10:30:41
感谢您的解决方案!但是我忘了在问题中提到的一件事,那就是我的 CSS 在其他域上......意思是,一个没有 ajax 响应的跨浏览器问题
2021-05-01 10:30:41
您在callback之间切换callBack应该是callback我觉得。
2021-05-07 10:30:41
@Munim:如果 css 在另一个域上,请尝试使用适当的类型、rel 和 href 以及 onload 函数添加“链接”标签(到头)。让我知道它是否有效。
2021-05-15 10:30:41

这实际上是我所做的。

为了确保加载特定的 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
});

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

如果我们不想自己加载css,这个解决方案仍然是最好的。(例如,如果我们使用装载机)
2021-04-23 10:30:41

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

想到了几个选项:

1)创建URL服务器端,完全避免这个问题。

2) 使用 setTimeout 检查样式是否已加载并每 20 毫秒左右检查一次,直到 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];
   }
在你敲它之前..先试试 - 本哈珀
2021-05-02 10:30:41