jQuery 已加载 html 内容 - 检查图像是否已加载和渲染

jQuery loaded html content - Check if images are loaded and rendered

我有标签逻辑,可以在包装器中加载 html 模板。这很好用,但我包含了一个动画,在切换标签时为标签包装器设置动画 height

问题如下:当模板包含 <img src="/some-image.png"> 时,有时会在浏览器显示图像之前执行 $('#tab-content').load('template-url', function() {...}) 回调函数。而且我的动画无法正常工作。

Code example (jsFiddle):

var currentHeight = $contentHolder.height();

$contentHolder.load(path, function() {
    $contentHolder.stop();

    function animateHeight() {
        var loadedContentHeight = $contentHolder.css('height', 'auto').height();
        $contentHolder.height(currentHeight);
        $contentHolder.animate({
            height: loadedContentHeight
        }, 800, 'linear');
    }
    animateHeight();
});

我尝试设置小超时,但每次都不起作用。如果我设置超过 300ms 的超时时间,感觉 tabs 的变化太慢了。

我试图在 $('img').load(function() {}) 被触发时执行动画,但没有成功。

此错误最常发生在网页完全刷新且每个选项卡内容首次加载时。

您可以调用 animateHeight 函数,因为已加载 HTML 中的每张图像都会依次加载。如果您有其他对象,例如视频,您可以扩大此选择。

// Call animateHeight as each image loads
var items = $('img', $contentHolder);
items.bind('load', function(){ 
    animateHeight();
});

已更新演示:http://jsfiddle.net/jxxrhvvz/1/

图像 load 事件有点损坏。要知道何时加载图像,您必须观察 DOM 的变化。然后在每次更改时,您必须获取所有新图像并从回调中向它们添加 onload 事件。为了防止每次都检查每个元素,一旦它们被加载,您可以通过添加 data-loaded="true" 属性 来标记它们。


监听 DOM 变化的一种方法是 MutationObserver 事件。 all modern browsers and IE11.

支持

可以在这个答案中找到更好的支持解决方案(IE9 及更高版本):Detect changes in the DOM。我不会在这里重复它(但它包含在下面的演示中)。


在每次 DOM 更改时,首先通过检查 element.complete.如果是,触发回调函数并向其添加属性。

如果 .complete 不是这种情况,请向它们添加一个 onload 事件,该事件也会在加载后触发回调。

在你的情况下,你只想在加载所有图像时触发你的回调,所以我添加了一个检查是否还有没有 data-loaded 属性的图像。如果您删除该 if 子句,您的回调将在每个图像加载后 运行。

// Observe the DOM for changes
observeDOM(document.body, function(){ 
    checkNewImages();
});

var checkNewImages = function() {
    var images = $('img:not([data-loaded]').each(function() {
        addImageLoadedEvent( this );
    });
}

var addImageLoadedEvent = function(img) {
    if (img.complete) {
        onImageLoaded(img);
    } else {
        $(img).on('load', function() {
            onImageLoaded(this);   
        });
    }
}

// The callback that is fired once an element is loaded
var onImagesLoaded = function(img) {
    $(img).attr('data-loaded', 'true');

    if($('img:not([data-loaded])').length === 0) {

        // YourCallbackHere();

    }
}

演示:fire event on all images loaded