0

This jQuery code loops through rows in a table and highlights each row as it goes. I have a stop button that sets a variable to false.

I know that I can break out of the .each loop by using return false;, but I want it to break out from within the queue.

How can I do this if the var is false?

$('.js-channel-notes tr').each(function(i) {
    $(this).delay((i++) * 160).queue(function() {
        $('.channel-row-highlight').removeClass('channel-row-highlight');
        $(this).addClass('channel-row-highlight').clearQueue();
    });
});
6
  • .queue() doesn't actually run the function. It just adds it onto a queue, to be ran at a later point with .dequeue(). Commented Dec 31, 2014 at 21:30
  • Impossible when using .each(). The loop ends long before the first .queue() starts. Don't use a loop at all. Instead select the elements, set up the first .queue(), and then when it runs, have it call the next, all the while keeping track of which index you're on. Commented Dec 31, 2014 at 21:30
  • If all you care about is highlighting, why not just use css? (the :hover pseudo selector is what you want) Example: jsfiddle.net/bfttLxsq Commented Dec 31, 2014 at 21:35
  • Have you tried break; ? Commented Dec 31, 2014 at 21:35
  • @Indigo the break statement works for loops constructed using keywords like for and while. The each function executes its supplied argument function for each element of a collection, and therefore a break inside that function would not impact the iterator in the each function itself. Commented Dec 31, 2014 at 21:38

2 Answers 2

1

Don't use .each() or .queue(). Just make a function that operates on the current element and delays the execution of the next call to the same function.

The current element is determined by an i counter that you increment on each call.

To break it, have a flag that is checked to exit the function immediately.

var tr = $('.js-channel-notes tr');
var i = 0;
var halt;

function next() {
    if (halt) return;

    $('.channel-row-highlight').removeClass('channel-row-highlight');
    tr.eq(i).addClass('channel-row-highlight');
    i++;
    if (i < tr.length) {
        setTimeout(next, 160);
    }
}

next();

Or skip jQuery altogether since there's so little being used there anyway.

var tr = document.querySelectorAll('.js-channel-notes tr');
var i = 0;
var halt;

function next() {
    if (halt) return;

    var c = document.querySelector('.channel-row-highlight');
    if (c) c.classList.remove('channel-row-highlight');
    tr[i].classList.add('channel-row-highlight');
    i++;
    if (i < tr.length) {
        setTimeout(next, 160);
    }
}

next();

There's far more engineering than is needed by using .delay() and .queue(). Simpler is better.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, thanks. I only recently added jQuery into my project and am still thinking about removing it again, this is one part where it is not required.
0

Apparently, you don't want an each.

You want a continuation, that you can 'conditionally' continue. Basically something like this (but unchecked, unrun):

var continuation = function(todo) {
    if (!todo.length) return;
    var head = todo[0];
    var tail = todo.slice(1); // or what is it
    head.delay(...).queue(function(){
         if (somecondition)
             continuation(tail);
    });
};
continuation($('.js-channel-notes tr'));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.