簡體   English   中英

如何檢查HTMLElement是否已完全加載

[英]How to check if an HTMLElement is fully loaded

運行此代碼:

 window.onload = function () { const sections = document.querySelectorAll("section"); let eT = []; for (let i = 0, len = sections.length; i < len; i++) { const el = sections[i]; if (el.parentNode.className !== "wrapper") { const wrapper = document.createElement("div"); wrapper.className = "wrapper"; el.parentNode.appendChild(wrapper); wrapper.appendChild(el); } const elCont = document.querySelectorAll(".wrapper")[i]; eT[i] = elCont.offsetTop; setTimeout(() => { console.log(eT[i], elCont.offsetTop) }, 100); } } 
 section{ width: 100vw; height: 1000px; position: relative; border: 1px solid; } body{ position: relative; } 
 <body> <section></section> <section></section> <section></section> <section></section> </body> 

如您所見,DOM操作然后讀取它們的offsetTops發生得太快了,因此,如果我在創建它們后立即讀取它們的offsetTops,將它們添加到主體中,然后將這些部分作為孩子添加到它們中,則值是錯誤的。 但是,如果我等待100毫秒,則值是正確的。 好的,設置超時將是解決問題的一種選擇,但是我認為必須有一個比這更優雅的解決方案。 有人知道這個解決方案嗎?

確實可以做到這一點,即返回到瀏覽器( setTimeout是一種方法, requestAnimationFrame是另一種方法)。 這樣一來,您就可以讓瀏覽器有時間來呈現結果,這是在添加元素的任務(在您的情況下,是運行load事件處理程序的任務)完成之后的某個時間發生的。

在大多數情況下, setTimeout的超時值為0是有效的; 過去,我不得不在Firefox上使用介於60到100之間的值,但是要在目標環境中進行測試。 您可能還需要處理requestAnimationFrame回調,該回調發生的時間比100ms要早得多(前提是瀏覽器未在某些事件上被阻止):

 window.onload = function () { const sections = document.querySelectorAll("section"); let eT = []; for (let i = 0, len = sections.length; i < len; i++) { const el = sections[i]; if (el.parentNode.className !== "wrapper") { const wrapper = document.createElement("div"); wrapper.className = "wrapper"; el.parentNode.appendChild(wrapper); wrapper.appendChild(el); } const elCont = document.querySelectorAll(".wrapper")[i]; eT[i] = elCont.offsetTop; requestAnimationFrame(() => { console.log(eT[i], elCont.offsetTop) }); } } 
 section{ width: 100vw; height: 1000px; position: relative; border: 1px solid; } body{ position: relative; } 
 <body> <section></section> <section></section> <section></section> <section></section> </body> 

該示例在Firefox,Chrome和Edge上對我有效(“對我有用” =>在rAF回調中, offsetTop代表0、1002、2004和3006)。

您也可以為此使用MutationObserver ,因為在將元素添加到DOM(此處為.wrapper )之后,它將觸發該.wrapper

 window.onload = function(){ const sections = document.querySelectorAll("section"); //https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver var tObserver = new MutationObserver(function(mutations){ if(mutations){ for(let i=0, len=sections.length; i<len; i++){ console.log('MutationObserver', sections[i].offsetTop) }; this.disconnect() } }); tObserver.observe(document, {attributes: false, childList: true, characterData: true, subtree: true}); let eT = []; for(let i=0, len=sections.length; i<len; i++){ const el = sections[i]; if(el.parentNode.className !== "wrapper"){ const wrapper = document.createElement("div"); wrapper.className = "wrapper"; el.parentNode.appendChild(wrapper); wrapper.appendChild(el); }; const elCont = document.querySelectorAll(".wrapper")[i]; eT[i] = elCont.offsetTop; console.log('in for loop', elCont.offsetTop); setTimeout(() => { console.log('in timeout', elCont.offsetTop) }, 100) } } 
 section{ border: 1px solid; height: 1000px; position: relative; width: 100vw } body{ position: relative } 
 <section></section> <section></section> <section></section> <section></section> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM