加载生成内容中的图片时的火灾事件

时间:2015-04-30 14:50:39

标签: javascript html javascript-events dom-events

我在使用Javascript生成的内容时遇到了问题:

我使用html页面的onload()事件从服务器加载HTML代码并将其注入页面。由于它已经是html,我使用我想要填充内容的节点的innerHtml属性。

一旦我注入了HTML,我就会调用一个手工制作的adjustHeights()函数来规范化我创建的元素的高度,使它们都与最高元素的高度相匹配。

除非innerHtml内的代码包含某种类型的图像或需要时间加载(特别是视频)的其他媒体,因此所有这些都能完美地工作,因为在注入代码和注入代码之间调用了adjustHeights()图像/视频等的加载时间结束。

在调用adjustHeights()之前,有没有办法等待加载每个元素?我已经尝试了document.onreadystatechange财产,但该州已经完成了#39;当我开始注入代码时。

如果可能,我宁愿不在adjustHeights()上使用基于时间的通话。

为了更清楚,这里有一个例子:

var mylist = document.getElementById('mycontent');
var li;
for (var i = 0; i < res.length; i++)
{
    li = document.create('li');
    li.innerHTML=res[i];
    mylist.appendChild(li);
}
adjustHeights();

2 个答案:

答案 0 :(得分:9)

要在不向所有图像/视频/等添加内联onload属性的情况下执行此操作,您必须观察DOM以进行更改。然后,在每次更改时,您都必须获取所有新媒体,并从回调中将onload事件添加到它们。为了防止每次检查每个元素,一旦加载它们,您可以通过添加data-loaded="true"属性来标记它们。

可以在此答案中找到用于观察DOM更改的跨浏览器解决方案:Detect changes in the DOM。我不会在这里重复(但它包含在下面的演示中)。

注意:我使用图片作为示例,但这也适用于视频和其他媒体。

在每次更改DOM时,首先检查图像是否已经加载了data-loaded属性,但是当图像仍然在浏览器的缓存中时,可能会检查element.complete 。如果是,则触发回调函数并将属性添加到其中。

如果.complete不是这种情况,请向其添加onload事件,并在加载后触发回调。

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

// Loop through all new media, add the event
var checkNewMedia = function() {

    // extend this by using document.querySelectorAll("img:not([data-loaded), video:not([data-loaded])") etc.
    var media = document.querySelectorAll('img:not([data-loaded]');
    for(var i = 0; i < media.length; i++) {
        addMediaLoadedEvent(media[i]);   
    }
}

// Fire the callback if complete, otherwise bind to onload
var addMediaLoadedEvent = function(element) {
    if (element.complete) {
        onMediaLoaded(element);
    } else {
        element.addEventListener('load', function(event) {
            onMediaLoaded(event.target);   
        });
    }
}

// The callback that is fired once an element is loaded
var onMediaLoaded = function(element) {
    element.setAttribute('data-loaded', 'true');

    adjustHeights(); // <-- your function
}

DEMO:fire event on each image load

如果您只想在加载所有图像后触发事件,则可以添加额外的检查,以计算仍未加载的图像数量:

// The callback that is fired once an image is loaded
var onMediaLoaded = function(element) {
    element.setAttribute('data-loaded', 'true');

    // only fire when there are no media elements without the 'data-loaded' attribute left
    // again, can be extended to use video, etc.
    if(document.querySelectorAll('img:not([data-loaded])').length === 0) {
        adjustHeights(); // <-- your function
    }
}

DEMO:fire event on all images loaded

答案 1 :(得分:1)

对于图像和其他类型的媒体,您应该使用“onload”事件,以便在此之后调用adjust height。 例如:

<img src="someimage.png" onload="loadImage()" >

<script>
   function loadImage() {
     // code to adjust heights
    }
</script>

以下是标准版本:

var img = document.querySelector('img')

function loaded() {
  alert('loaded');
  // do something to adjust height
}

if (img.complete) {
  loaded()
} else {
  img.addEventListener('load', loaded)
  img.addEventListener('error', function() {
      alert('error')
  })
}