9

I am trying to have the class of each elements change one at a time in sequence automatically. This means element 1 glows then goes off as element 2 glows and then goes off and so on. When each element has glowed once the whole sequence starts over.

$('header div:first').toggleClass('highlight').nextAll().toggleClass('none');

function highlight() {
  var $off = $('header div.highlight').toggleClass('none');

  if ($off.next().length) {
    $off.next().toggleClass('none');
  } else {
    $off.prevAll().last().toggleClass('highlight');
  }
}

$(document).ready(function() {
  setInterval(highlight, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
 <div>element 1</div>
 <div>element 2</div>
 <div>element 3</div>
 <div>element 4</div>
</header>

It wont work as expected (elements 2 through 4 highlight all at the same time and then go off while element 1 doesnt change at all) and I dont know why. What am I doing wrong?

user2226755
  • 12,494
  • 5
  • 50
  • 73
Cain Nuke
  • 2,843
  • 5
  • 42
  • 65

4 Answers4

5

So yes, you don't need the .none. Simply use your default styles and the .highlight class.
Get the number of items, create a counter, increment it and loop it using % Reminder Operator:

jQuery(function( $ ) { // DOM is ready

  var $el = $("header>div"), tot = $el.length, c = 0;

  $el.eq(c).addClass("highlight"); // initial highlight

  setInterval(function() {
    $el.removeClass("highlight").eq(++c%tot).addClass("highlight");
  }, 1000);

});
header > div           { transition:0.5s; -webkit-transition:0.5s; }
header > div.highlight { color:#f0f; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
 <div>element 1</div>
 <div>element 2</div>
 <div>element 3</div>
 <div>element 4</div>
</header>

Some docs:
https://api.jquery.com/eq/
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder_()

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
4

The none class along with the toggleClass() calls can be a bit confusing to read through. You may be better off by simply keeping track of your current highlighted element via div.highlight and determining which one to target next using the updated code below :

function highlight() {
    // Remove the highlight from all options
    var $current = $('div.highlight');
    // Store the next one
    var $next = $current.next('div');
    // Remove all highlighting
    $('div.highlight').removeClass('highlight')
    if($next.length){
      $next.addClass('highlight');
    } else {
      $('header div:first').addClass('highlight');
    }
}
// When the document is ready
$(function() {
    // Initially set your first element as highlighted and start your interval
    $('header div:first').addClass('highlight');
    setInterval(highlight, 1000);
});

Example

You can see an example of this in action here and demonstrated below :

enter image description here

Image is for example purposes only and timing may appear different than actual code executing... :)

Rion Williams
  • 74,820
  • 37
  • 200
  • 327
3

Solution :

Change .none by .highlight, like this :

$('header div:first').toggleClass('highlight');

function highlight() {
  var $off = $('header div.highlight').toggleClass('highlight');

  if ($off.next().length) {
    $off.next().toggleClass('highlight');
  } else {
    $off.prevAll().last().toggleClass('highlight');
  }
}

$(document).ready(function() {
  setInterval(highlight, 1000);
});
.highlight {
   color:red; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
 <div>element 1</div>
 <div>element 2</div>
 <div>element 3</div>
 <div>element 4</div>
</header>

Other ways :

$('header div:first').toggleClass('highlight');

setInterval(function() {
  var abc = "highlight";
      $off = $('header div.' + abc),
      $next = $off.next().length ? $off.next() : $off.prevAll().last();

  $off.toggleClass(abc);
  $next.toggleClass(abc);
}, 1000);
.highlight {
   color:red; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
 <div>element 1</div>
 <div>element 2</div>
 <div>element 3</div>
 <div>element 4</div>
</header>
user2226755
  • 12,494
  • 5
  • 50
  • 73
  • Thanks. Your code works perfect but I have one question. You put the javascript inside or right before ? Because I tried it on my end and it wont work. – Cain Nuke May 05 '16 at 19:10
  • That vanilla JavaScript case selection is tried and true. I so need to incorporate it more in my code to `?` write more code `:` write less code`;` – Alexander Dixon May 05 '16 at 19:11
  • @CainNuke http://stackoverflow.com/questions/10994335/javascript-head-body-or-jquery I prefer to let you to make your own choice. If you have several js lib, I advice you to use [requirejs](http://requirejs.org/). – user2226755 May 05 '16 at 19:19
  • My original code worked included in but yours only works if within body. Is there any reason for that? – Cain Nuke May 05 '16 at 19:23
  • @CainNuke I don't know. You can use `$(document).load(function() { /* code here */ });` to fix it. – user2226755 May 05 '16 at 19:26
1

You could try this approach.

Javascript

var highlight = function(){
$('header div').removeClass('highlight');
$('header div').each(function(i,v) {
setTimeout(function(){$(v).prev().toggleClass('highlight');$(v).toggleClass('highlight');}, i*1000);
});
setTimeout(highlight, ($('header div').length)*1000);
};
highlight();

Fiddle