Home > Software engineering >  Execute Javascript after 2 seconds
Execute Javascript after 2 seconds

Time:09-17

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

  • Related