4

如何防止jQuery$('body').load('something.php');更改任何DOM,直到something.php(包括图像,js)的所有内容完全 加载

- 可以说一些实际内容是:

Hello world

something.php内容是:

image that loads for 10 seconds
20 js plugins

触发 .load() 函数后什么都不会发生,直到图像和 js 文件完全加载,并THEN立即更改内容。

可能会出现一些预加载器,但它不是问题的主题。

[编辑] - - - - - - - - - - - - - - - - - - - - - - - - ----------------------

我的解决方案是跨浏览器不透明度为 0 的 css 代码(总是在构建 dom 之前加载 css)。

.transparent{
    -moz-opacity: 0.00;
    opacity: 0.00;
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha"(Opacity=0);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
    filter:alpha(opacity=0);
}

它通常但并非总是防止内容的不良闪烁。现在它可以以某种方式检测到内容是由 jQuery ajax 加载的,并应用一些显示超时等等。但实际上问题仍然存在。

现在为这个问题做一个更简单的例子:

单击触发 .load('something.php') 函数的链接后,如何在 $('body').load('something.php') 之后以 3000 毫秒的延迟开始更改 DOM?(浏览器应该立即开始下载,但 DOM 更改必须稍后启动)

4

4 回答 4

3

改用.get并在成功回调中分配内容:

$.get('something.php', function(result) {
    $('body').html(result);
});
于 2012-12-04T10:42:35.317 回答
1

您可能需要自己解决一些实现细节,但这里有一个粗略的解决方案:

  1. 不要.load()直接使用。无法更改为等待所有图像加载。

  2. 用于$.get()将 HTML 提取到变量中,我们称之为frag.

  3. 用于$(frag).find('img').each(fn)查找所有图像并将每个图像转储this.src到预加载器中。

    var images = [], 
    $frag = $(frag),
    loaded = 0;
    
    function imageLoaded()
    {
        ++loaded;
        // reference images array here to keep it alive
        if (images.ready && loaded >= images.length) {
            // add $frag to the DOM
            $frag.appendTo('#container');
        }
    }
    
    $frag.find('img').each(function() {
        var i = new Image();
        i.onload = i.onerror = imageLoaded;
        i.src = this.src;
    
        images[images.length] = i;
    });
    
    // signal that images contains all image objects that we wish to monitor
    images.ready = true;
    

    演示

  4. 加载所有图像frag后,使用$frag.appendTo('#container').

于 2012-12-04T10:44:00.900 回答
0

这是一个概念的快速证明,它在将 HTML 片段插入 DOM 之前加载相关图像:http: //jsfiddle.net/B8B6u/5/

您可以使用 onload 处理程序预加载图像以触发迭代:

var images = $(frag).find('img'),
loader = $('<img/>');

function iterate(i, callback) {
    if (i > 0) {
        i--;
        loader.unbind("load");
        loader.load(function() {
            iterate(i, callback);
        });
        loader.attr('src', images[i].src);
    }else{
        callback();
    }
}

iterate(images.length,function(){
    $('#container').html(frag);
});

这应该可以工作,因为每个图像都是在前一个图像完成加载之后加载的。

于 2012-12-04T11:18:26.937 回答
0

你试过这个吗?

$(function(){$('body').load('something.php')});

编辑:我刚刚意识到您实际上是想等待东西加载,然后再将其放入体内。

以下是指向类似问题的三个链接。

使用 jQuery 预加载图像

是否可以使用 ajax/jquery 技术预加载页面内容?

使用 PHP 和 jQuery 预加载图像 - 逗号分隔数组?

您也可以将它们调整为脚本。

这也可能奏效。

  $.ajax({
    'url': 'content.php',
    'dataType': 'text',
    'success': function(data){
        var docfrag = document.createDocumentFragment();
        var tmp = document.createElement('div'), child;
        //get str from data here like: str data.str
        tmp.innerHTML = str;
        while(child = tmp.firstChild){
            docfrag.appendChild(child);
        }
        $('body').append(docfrag);
    }
  });

按照影子向导的建议,这是一种更长的方法,但它可能会奏效。嗯。没关系。杰克的回答看起来最好。我会等一会儿,如果没有人喜欢我的答案,我会删除它。

编辑:看起来附加到文档片段可以做http请求。任何使用 createDocumentFrament 的脚本都可以从预加载中受益。

在这个问题中,即使 createDocumentFragment 正在这样做,他们也不需要 http 请求: Using documentFragment to parse HTML without sent HTTP requests

我不能确定这是否适用于所有浏览器或仅在运行 console.log 时,但如果这种行为是通用的,它可能是一个很好的预加载选择。

于 2012-12-04T10:36:53.337 回答