0

On click I want to check if foo has class of bar if not then check again after 5 seconds if so then perform action and stop checking.

jQuery(document).ready(function($) {
  $( "#foo" ).click(function() {
    function bar(){
      if $(this).hasClass('bar') {
        return true;
      } else {
    setTimeout(bar, 5000);
      }
    }  
  });
});

Ive tried to create a function called bar which checks if foo has class of bar if not then wait 5 seconds and try again. I am executing this once foo has been clicked but something isn't working.

How can I check a div has class if so perform an action if not check again every 5 seconds until it has a class?

2 Answers2

0

To continuously run some logic use an interval instead of a timer. To clear the interval, save a reference to it and then call clearInterval() when the relevant condition is met. Something like this:

jQuery(document).ready(function($) {
  var $foo = $('#foo'),
    interval;

  function bar() {
    if ($foo.hasClass('bar')) {
      console.log('class added!');
      clearInterval(interval);
    }
  }

  $foo.click(function() {
    clearInterval(interval);
    if (!$foo.hasClass('bar'))
      interval = setInterval(bar, 5000);
  });
});

However it should be noted that a much better way to achieve what you require is to use a MutationObserver which will trigger your logic when the class is added, without the need to constantly poll the DOM.

Here is an answer detailiing how that can be done.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

You have some syntax issues, you do not call bar so it never runs, and issues with this since setTimeout changes the scope to window.

jQuery(document).ready(function($) {
  var timer;
  $("#foo").on("click", function() {
    if (timer) return
    function bar() {
      if ($(this).hasClass('bar')) {
        timer = null;
        console.log("It was added")
      } else {
        timer = setTimeout(bar.bind(this), 1000);
      }
    }
    bar.apply(this)
  });
})

window.setTimeout(function () {
  $("#foo").addClass("bar")
}, 1000 * (Math.random() * 20))
.bar {
  background-color: lime;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button type="button" id="foo">click</button>

To avoid the binding, you can move the this outside the method so you are not always look up the element.

jQuery(document).ready(function($) {
  var timer;
  $("#foo").on("click", function() {
    if (timer) return
    var btn = $(this)
    function bar() {
      if (btn.hasClass('bar')) {
        timer = null;
        console.log("It was added")
      } else {
        timer = setTimeout(bar, 1000);
      }
    }
    bar()
  });
})

window.setTimeout(function () {
  $("#foo").addClass("bar")
}, 1000 * (Math.random() * 20))
.bar {
  background-color: lime;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button type="button" id="foo">click</button>
epascarello
  • 204,599
  • 20
  • 195
  • 236