我在使用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();
答案 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
}
如果您只想在加载所有图像后触发事件,则可以添加额外的检查,以计算仍未加载的图像数量:
// 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
}
}
答案 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')
})
}