是否可以确定何时加载了innerHTML? 我不确定它是否是同步操作。我假设'构建DOM'是同步的,但加载标签,内容等不是。
简而言之 - 当innerHTML完成加载时,是否有办法获取事件?
谢谢!
答案 0 :(得分:17)
您需要使用DOM Mutation Observers,目前只适用于Chrome and Firefox。 它们取代了杀死性能的DOM Mutation Events。
示例代码,来自HTML5Rocks:
var insertedNodes = [];
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
for (var i = 0; i < mutation.addedNodes.length; i++)
insertedNodes.push(mutation.addedNodes[i]);
})
});
observer.observe(document, { childList: true });
console.log(insertedNodes);
这是DOM4 spec。
请不要使用setTimeout()
黑客。 :)
答案 1 :(得分:1)
因为通过innerHTML添加的img元素会触发它们的onload事件,所以你可以在插入innerHTML的原始代码的末尾添加一个小图像,并且在它们的onload事件中你可以调用一个函数。你也可以在那里删除图像。
<img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' onload='hasLoadedFunc();this.parentNode.removeChild(this);'>
src ='data:image'代码在这里很有用,因为不需要特定的图像。
我在另一个答案中找到了这个解决方案,我找不到它。一旦找到参考,我将编辑此解决方案。
答案 2 :(得分:0)
var waitUntil = function (fn, condition, interval) {
interval = interval || 100;
var shell = function () {
var timer = setInterval(
function () {
var check;
try { check = !!(condition()); } catch (e) { check = false; }
if (check) {
clearInterval(timer);
delete timer;
fn();
}
},
interval
);
};
return shell;
};
像这样使用:
waitUntil(
function () {
// the code you want to run here...
},
function() {
// the code that tests here... (return true if test passes; false otherwise)
return !!(document.getElementById('<id of the div you want to update>').innerHTML !== '');
},
50 // amout to wait between checks
)();
答案 3 :(得分:0)
如果您替换整个文档 HTML,那么 @zahanm 答案似乎不起作用,这正是我所需要的。所以我不得不退回到setInterval
。根据 @shawndumas 的回答,我使用 Promise 创建了一种更现代的方法:
function waitUntilSelectorExist(selector, interval = 100, timeout = 20000) {
let intervalId;
let elapsed = 0;
let promise = new Promise(function(resolve, reject) {
intervalId = setInterval(() => {
let element = document.querySelector(selector);
if (element !== null) {
clearInterval(intervalId);
resolve(element);
}
elapsed += interval;
if (elapsed > timeout) {
clearInterval(intervalId);
reject(`The selector ${selector} did not enter within the ${timeout}ms frame!`);
}
}, interval);
});
return promise;
}
我也使用 querySelector
代替,因此您可以搜索您喜欢的任何选择器,.class
、#id
等。
如果函数在文档中找到 querySelector
,Promise
将解析,因此您可以将它与新的 await
关键字一起使用。
(async() => {
try {
await waitUntilSelectorExist("#test");
console.log("Do stuff!");
} catch (error) {
console.warn(error); // timeout!
}
})();
当然,如果您真的只是更改文档中的某些元素,您也可以将 MutationObserver
包裹在 Promise
中:
function waitUntilSelectorExist(selector) {
let MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
let promise = new Promise(function(resolve) {
let observer;
observer = new MutationObserver(function(mutations) {
let element = document.querySelector(selector);
if (element !== null) {
observer.disconnect();
resolve();
}
});
observer.observe(document.body, { childList: true, subtree: true });
});
return promise;
}
答案 4 :(得分:-2)
是的,你可以这样做:
window.document.getElementById("Testing").innerHTML =
"<img src='test.jpg' width='200' height='400'>";
alert('test');
javascript将按顺序执行,因此一旦加载了innerHTML,警报就会消失。
答案 5 :(得分:-2)
如何创建容器div并向其添加onload事件处理程序。
var container = document.createElement('div');
container.addEventListener('load', function() {
// Do something here
}, false);
container.innerHTML = '<h1>Here comes my HTML</h1>';
document.getElementById('someId').appendChild(container);
答案 6 :(得分:-2)
您是否尝试过使用window.onload
事件?整个页面完全加载时会触发此事件,包括图像,脚本,内部框架等所有内容。
P.S。如果您使用JQuery库,那么您可以使用他们的$(window).load
事件包装器。