I am trying to use setInterval
or setTimeout
but the primary element getting removed.
Code without Javascript delay : Working fine
const selectAllWithAttributeAdStatus = document.querySelectorAll("[data-ad-status]");
selectAllWithAttributeAdStatus.forEach(ad => {
if ((ad.getAttribute("data-ad-status")) === "unfilled") {
document.write("<h1>Unfilled</h1>");
} else {
document.write("<h1>Filled</h1>");
};
})
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="unfilled"> <img src="https://place-hold.it/338x280" /></div>
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="somethingelse"><img src="https://place-hold.it/338x280" /></div>
Code with Javascript delay : Working fine but the element getting removed
const selecteAd = () => {
const selectAllWithAttributeAdStatus = document.querySelectorAll("[data-ad-status]");
selectAllWithAttributeAdStatus.forEach(ad => {
if ((ad.getAttribute("data-ad-status")) === "unfilled") {
document.write("<h1>Unfilled</h1>");
} else {
document.write("<h1>Filled</h1>");
};
})
}
const myTimeout = setTimeout(selecteAd, 2000);
//const myTimeout = setInterval(selecteAd, 2000);
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="unfilled"> <img src="https://place-hold.it/338x280" /></div>
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="somethingelse"><img src="https://place-hold.it/338x280" /></div>
I want to delay JavaScript without getting element removed.
CodePudding user response:
Do not use document.write
as it can have very strange behaviour and it can affect the state of HTML parser, so your DOM elements might be removed.
https://developer.mozilla.org/en-US/docs/Web/API/Document/write
Instead, you can make 2 paragraphs on your page for example, hide them both, and show them after 2 seconds.
One more thing, do not use inline css, always keep css outsourced in the seperate file.
I adapted your code snippet below. Keep in mind this can be written much smarter and cleaner with toggling classes in css instead of changing css directly with javascript (which you should avoid when possible), but for the sake of you question, I did it this way.
const selecteAd = () => {
const selectAllWithAttributeAdStatus = document.querySelectorAll("[data-ad-status]");
selectAllWithAttributeAdStatus.forEach(ad => {
if ((ad.getAttribute("data-ad-status")) === "unfilled") {
document.querySelector(".unfilledText").style.display = 'block';
} else {
document.querySelector(".filledText").style.display = 'block';
};
})
}
const myTimeout = setTimeout(selecteAd, 2000);
//const myTimeout = setInterval(selecteAd, 2000);
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="unfilled"> <img src="https://place-hold.it/338x280" /></div>
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="somethingelse"><img src="https://place-hold.it/338x280" /></div>
<p class='unfilledText' style="display: none;">Unfilled</p>
<p class='filledText' style="display: none;">Filled</p>
CodePudding user response:
The problem here is with the document.write
method. To summarize the documentation, document.write
has different behavior when the document is loading versus when it's been loaded. In your first example, the script is running while the document is in the "loading" state. This writes the given text to the DOM, keeping what is already written to it. However, once the page has been fully loaded like in your second example, this method will replace everything in the DOM with whatever you give it. Also according to the aforementioned documentation, it's a very bad idea to use this method period.
A better idea would be to use document.append
instead. This will always add the element(s) to the DOM without replacing anything. Unfortunately you can't just pass the HTML in as a string, but it's still pretty simple to use.
const selecteAd = () => {
const selectAllWithAttributeAdStatus = document.querySelectorAll("[data-ad-status]");
selectAllWithAttributeAdStatus.forEach(ad => {
var elem = document.createElement('h1')
if ((ad.getAttribute("data-ad-status")) === "unfilled") {
elem.innerText = 'Unfilled'
} else {
elem.innerText = 'Filled'
}
document.body.append(elem);
})
}
const myTimeout = setTimeout(selecteAd, 2000);
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="unfilled"> <img src="https://place-hold.it/338x280" /></div>
<div style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-1714167228247329" data-ad-slot="8611448539" data-adsbygoogle-status="done" data-ad-status="somethingelse"><img src="https://place-hold.it/338x280" /></div>
CodePudding user response:
Document.write overwrites complete document content if called after loading document. Use div element and add text content to it