3

我想通过 JS 动态插入一些 HTML 内容和一些 CSS url。

我有 3 个以上的 CSS 文件。我希望在我的内容插入页面之前下载它们。

有没有办法查出上述文件是否已经下载?

这是它应该如何工作的:

  • 下载css文件;
  • 下载完所有 css 文件后显示 HTML;
  • 插入HTML后开始加载JS文件;
  • 加载完所有 JS 文件后触发回调;
4

10 回答 10

3

来源: https ://stackoverflow.com/a/3794242/1292652

使用 AJAX 检索 CSS 文本

您可以使用 AJAX 函数创建动态 CSS URL 并将其作为纯文本获取,而不是使用混乱的解决方法来确定 CSS 是否已加载。

插入 CSS

获取原始文本后,您可以使用此函数将 CSS 插入style标签并添加回调:

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("CSS loaded, you can show the dialog now :)");
})

允许跨域 AJAX

在您的评论中,您提到您必须加载jQueryjQueryUI我猜想在不同的域上加载。

要绕过 AJAX 跨域限制,请查看此链接链接或此

于 2012-09-24T17:41:24.700 回答
3

您可以使用YepNope.js,YepNope 允许您构建异步条件测试以查看资源是否已加载。测试通过后,您可以告诉它注入新的 CSS 或 JS 文件。

下面的示例取自 YepNope.js 站点。

yepnope.injectCss( stylesheetSource [, callback ] [, elemAttributes ] [, timeout ]);

// Example
yepnope.injectCss("print.css", function () {
  console.log("css injected!");
}, {
  media: "print"
}, 5000);

您甚至可以让 YepNope 先加载初始 CSS 文件,然后在完成加载后,YepNope 可以触发回调来执行其他任务,例如加载更多 JS 或 CSS 文件。

于 2012-09-26T08:52:44.157 回答
1
<html>
<head>
   <!-- 
       Put your styles here.  Make sure the *last* CSS file has the following:
       body { display: block !important }

       This will allow the stylesheets to load while the body is hidden.  
       When the last stylesheet is loaded, the body will be visible.
   -->
</head>

<body style="display: none">
    <!-- Lots of HTML here -->

    <!-- 
        Put your script tags here.
        In the first script, I recommend binding to the window.load event...  
        which will be fired once all your scripts are done loading.
    -->
</body>
</html>
于 2012-09-28T03:51:58.793 回答
0

我认为这有点符合您的要求:

<html>
  <head>
    <!-- CSS Stuff goes here -->
    <!-- JS Stuff come right after -->
  </head>
  <body>
    <!-- HTML Stuff comes withing Body -->
  </body>
</html>

这将导致:-

  1. 并行下载所有 CSS 文件;
  2. 然后解析并显示 HTML 内容;
  3. 浏览器获取所有 JS;
  4. JS 是 tun,它可以做任何它想要的插入;

你的问题有点混乱,你能澄清一下吗?我不明白你为什么需要这样的订单,你能给出大图吗?JS 旨在成为一种即发即弃的语言,查看是否所有内容都已下载会很尴尬。这对您有意义和/或对您有帮助吗?

于 2012-09-21T14:24:02.157 回答
0

我知道这不是一个很好的解决方案,但是您可以使用 AJAX 获取 CSS 文件并将其内容添加到 a <style>,而不是将 a 插入<link>到 DOM。使用 AJAX,您可以确定何时完全下载 CSS,并根据您的条款将整个内容添加到页面中。

于 2012-09-24T10:05:34.153 回答
0

来源: https ://stackoverflow.com/a/8122005/1292652

出于同样的原因,我不建议您这样做,因为您不应该使用while循环来实现sleep(),但如果必须,您可以尝试一下。

在链接的答案中,添加了参考样式。例如:#ensure-cssload-8473649 { display: none }。但是由于您正在下载不受您控制的文件,因此您必须从工作表中选择一些样式进行检测。

cssLoad()功能是:

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": <insert element CSS applies to>,
     css: <insert sample CSS styles>
}, function () {
    console.log("CSS loaded, you can show the dialog now :)");
});
于 2012-09-24T18:18:13.680 回答
0

你为什么不在页面上添加一个元素并检查它应该有一些 js 的一些样式。如果它具有该样式,则该样式表可能已加载。

像这样:

if (document.getElementById("csspage-3-box").style.color === "#somethingUnique") {
    //it is loaded
}

您可以附加一些隐藏的 div,其 ID 对每个样式表都是唯一的。如果他们有任何样式,那么您就知道您想要的工作表已加载。这个手术很便宜。它确实添加了一些非语义的 div 元素。话虽如此,我觉得每个人的 DOM 中都至少有一个非语义元素。

只是一个建议,但 3 个 css 文件并不多。其他简单的解决方案包括:

A)您可以只对它们进行 cat 和缩小,然后一次将它们全部交付。
B) 将它们扔到 CDN 上(如 aws s3 + cloudfront),这非常便宜,它们将被并行加载。
C) 照常加载它们。您也可以将它们放在子域中。

现在,如果我是你,我会把我的 CSS 分成一堆文件。3 文件太少。我会分离出网格和每个元素类型。然后在每页(或页组)的基础上重新组合它们。这使您可以根据需要包含每个单独的部分。

毕竟附加一个链接标签是相当容易的(只要你能很容易地得到它的路径)。我建议使用链接而不是样式标记,因为如果您确实使用 CDN 路由或子域路由,如果尝试使用一些 xhr 获取 css 文件的内容,则会遇到跨域问题。

于 2012-09-24T19:11:45.150 回答
0

在构建我们团队开发的应用程序时,可能会有许多 CSS 和脚本文件,而您的 HTML 的头部最终可能看起来相当麻烦。我构建了一个小脚本,它将通过将文件作为数组传递给方法来加载所有文件。但是,我在自己的脚本文件中有 loadCSS(),我只是通过 HTML 中的脚本标记调用并传入数组。代码采用整体格式,以便于查看。

window.onload = function() {//Use $(document).ready() if using jQuery

    var cssArray = ["Style01.css", "Style02.css", "Style03.css"];
    loadCSS(cssArray, function () {

        alert("Style sheets have been loaded.");    
    });
    //Note: You can do a similar process for the JS files.
    //Load HTML when CSS is finished - Shown below
    loadHTML(); 
}

function loadCSS(array, callback) {

var cssArray = array;

    for (var i = 0; i < cssArray.length; i++)
    {
        document.write("<link rel='stylesheet' type='text/css' href='styles/" + cssArray[i] + "' />");
        //console.log(cssArray[i] + " style sheet has been loaded.");

        //Detects when for loop is finished evaluating the Array
        if (i == cssArray.length - 1) {

            return callback();
        } 
    }

    //loadHTML() can also be invoked here to ensure CSS files have been loaded.
}

如果您尝试动态构建一些 HTML,那么您可以在加载 CSS 文件后尝试类似的操作。

function loadHTML() {

//Create Main Table
var mainTable = document.createElement("table");
mainTable.id = "mainTable";
mainTable.cellPadding = 0;
mainTable.cellSpacing = 0;
mainTable.border = 0;       

//Create Body
var mainBody = document.createElement("tbody");   

//Create Table Row
var mainTR = document.createElement("tr");
mainTR.style.height = "50px";
mainTR.className = ""; //Insert class from one of the style sheets

//Create Main Cell
var mainTD = document.createElement("td");
mainTD.id = "mainTD";
//mainTD.style.width = "";
mainTD.style.textAlign = "left";
mainTD.style.padding = "5px 10px 5px 10px";
mainTD.className = ""; //Insert class from one of the style sheets
mainTD.innerHTML = "Test Text";

mainTR.appendChild(mainTD); 
mainBody.appendChild(mainTR);
mainTable.appendChild(mainBody);     

document.body.appendChild(mainTable);               
}

如果您有任何问题,请随时提问。尽管已经发布了一些很好的示例,但希望这会有所帮助。

于 2012-09-26T20:24:20.483 回答
0

关于什么 :

$(document).ready(function() {
    $("body").hide();
});

然后,在下载的 css 文件中:

body { diaplay:block; }
于 2012-09-30T13:12:46.967 回答
0

用于loadCSS加载您的CSS. 并在内部onload方法中放置您要在所有 css 加载后执行的代码。

var counter = 0;
function onload(){
   counter--;
    setTimeout(function(){ // insuring if loaded immediately 
        if(counter == 0){ 
       // your code  here //******** CODEREPLACE ************/
          alert('all css files loaded!');
         }
    });
}
function loadCSS(href){
    counter++;
    l  = document.createElement('link');
    l.href = href;
    l.onreadystatechange = function () { // For IE
          if (this.readyState == 'loaded'){
              onload.call( this );
           }
     };
    l.rel = 'stylesheet';
    l.type='text/css';
    l.onload = onload;
    document.getElementsByTagName('head')[0].appendChild(l);
}

loadCSS('http://www.google.co.in/search?q=load+css+files+dynamically&aq=f&oq=load+css+files+dynamically&sugexp=chrome,mod=1&sourceid=chrome&ie=UTF-8');
于 2012-09-30T13:52:19.240 回答