0

Currently what I'm trying to do is have a function that looks for if the #discountbox element is visible then clone that #discountbox element and place it after .pricebox. Right now what's happening is that it is placing it after .pricebox and cloning it indefinitely.

How can I get the setInterval to stop after it finds #discountbox and clones it once?

HTML

<div id="discountbox" class="discount-summary">
      You get $5 Off
</div>

<div id="modal">
    <span class="price-box">
      $20.50
    </span>
</div>

Javascript

jQuery(document).ready(addDiscountsummary);

function addDiscountsummary () {
if($('#discountbox').is(':visible')){  //if the container is visible on the page
      $("#discountbox").clone().insertAfter("#modal span.price-box"); //insert add to cart button after view contents buttons     
    } else {
      setInterval(addDiscountsummary, 1000); //check every 1000 ms
    }
}
Felicia Santos
  • 401
  • 3
  • 16
  • You want to use `setTimeout` instead of `setInterval`. As the code is written now, it will setup multiple intervals which will never be cleared. Using `setTimeout` it will stop setting a timeout after #discountbox is visible. – Mordred Jun 17 '21 at 03:28
  • https://stackoverflow.com/questions/109086/stop-setinterval-call-in-javascript – Program_Lover Jun 17 '21 at 03:32
  • 1
    What is the event that makes the element visible? Why not use its event to insert the modal? – dale landry Jun 17 '21 at 03:34
  • 2
    Does this answer your question? [Stop setInterval call in JavaScript](https://stackoverflow.com/questions/109086/stop-setinterval-call-in-javascript) – Program_Lover Jun 17 '21 at 03:37
  • @Mordred I've tried using setTimeout but it results in #discountbox not being found. #discountbox does not appear on the page on load, it appears after a couple of items are added to a cart. – Felicia Santos Jun 17 '21 at 16:17

4 Answers4

0

you're looking for clearInterval() or as mentioned, a better solution would be to use setTimeout and clearTimeout instead

jQuery(document).ready(addDiscountsummary);

function addDiscountsummary () {
   if($('#discountbox').is(':visible')){  //if the container is visible on the page
      $("#discountbox").clone().insertAfter("#modal span.price-box");
      clearTimeout(window.nextTimeout);
   } else {
      window.nextTimeout = setTimeout(addDiscountsummary, 1000); //check every 1000 ms
   }
}
stackoverfloweth
  • 6,669
  • 5
  • 38
  • 69
0

After it finds the button Call clearInterval() method to stop your interval.

0

clearInterval(intervalID) will do the trick. When your doc loads, set the interval. Make sure the ID (which I am calling interval) is first created outside of any function, available to the rest of the page. When your item is found, clearInterval(interval)

let interval
jQuery(document).ready(function() {
  interval = setInterval(addDiscountsummary, 1000);
});

function addDiscountsummary() {
  if ($('#discountbox').is(':visible')) {
    $("#discountbox").clone().insertAfter("#modal span.price-box");
    clearInterval(interval)
  }
Kinglish
  • 23,358
  • 3
  • 22
  • 43
0

Try adding:

var testData = !!document.getElementById("discountbox");
if(testData=="true"){clearInterval(addDiscountsummary)}
else{};

To your code. This checks if the element exists in the code and returns true if the element exists:

var testData = !!document.getElementById("discountbox");

This stops the loop testData returns true.

if(testData=="true"){clearInterval(addDiscountsummary)}
Tejas Gupta
  • 496
  • 2
  • 8
  • This isn't correct. The function is not the interval id. The interval id has to be explicitly set and is a variable, not a method – Kinglish Jun 17 '21 at 03:56