[英]Event to determine when innerHTML has loaded
是否可以確定何時加載了 innerHTML? 我不確定這是否是同步操作。 我假設“構建 DOM”是同步的,但加載標簽、內容等不是。
所以簡而言之 - 有沒有辦法在 innerHTML 完成加載時獲取事件?
謝謝!
您需要使用DOM Mutation Observers ,目前僅適用於Chrome 和 Firefox 。 它們取代了破壞性能的 DOM 突變事件。
示例代碼,來自 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 規范。 請不要使用setTimeout()
黑客。 :)
由於通過innerHTML 添加的img 元素確實觸發了它們的onload 事件,您可以在插入innerHTML 的原始代碼的末尾添加一個小圖像,並且在它們的onload 事件中您可以調用function。 您也可以刪除那里的圖像。
<img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' onload='hasLoadedFunc();this.parentNode.removeChild(this);'>
src='data:image' 代碼在這里很有用,因為不需要特定的圖像。
我在另一個答案中找到了這個解決方案,我只是找不到它。 找到參考后,我將編輯此解決方案。
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
)();
如果您替換整個文檔 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
等。
如果 function 曾經在文檔中找到querySelector
,則Promise
將解析,因此您可以將其與新的await
關鍵字一起使用。
(async() => {
try {
await waitUntilSelectorExist("#test");
console.log("Do stuff!");
} catch (error) {
console.warn(error); // timeout!
}
})();
當然,如果您真的只是更改文檔中的某些元素,您也可以在Promise
中包含MutationObserver
:
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;
}
如果您的問題是等到元素上的 innerHTML 已完全呈現和繪制,例如測量元素的最終大小,請在頂級或異步函數中使用此代碼:
await YieldForFrame();
await YieldForFrame();
以下代碼是您程序的一部分:
function YieldForFrame()
{
// Create Promise for use with 'await'
return new Promise(function(resolve, reject)
{
requestAnimationFrame(resolve);
});
} // YieldForFrame
如何創建一個容器 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);
您是否嘗試過使用window.onload
事件? 此事件在整個頁面完全加載時觸發,包括其所有內容,如圖像、腳本、內框等。
PS 如果你使用 JQuery 庫,那么你可以使用他們的$(window).load
事件包裝器。
是的,你可以這樣做:
window.document.getElementById("Testing").innerHTML =
"<img src='test.jpg' width='200' height='400'>";
alert('test');
javascript 將按順序執行,因此一旦加載了您的 innerHTML,警報將關閉 go。
另外,看看Javascript 執行 Model
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.