2

Javascript isn't my forte, so I'm looking for help : How would you write a function which add a Class to 3 elements with interval ?

 <ul>
   <li class="panel">Item 1</li>
   <li class="panel">Item 2</li>
   <li class="panel">Item 3</li>
 </ul>

The idea is to add an .--active class on the 1st item when document is ready and remove it after 2sec to add it to the 2nd item and so on.

7 Answers 7

3

If you're using jQuery you could loop through the li's using the index, and reset the index to 0 when you reach the last li element :

if( $('li.panel.active').index() == lis_count-1 )
    active_li_index  = 0;
else
    active_li_index++;

Hope this helps.

jQuery solution:

$(function(){
   var lis_count = $('li.panel').length;
   var active_li_index = 0;
   
   setInterval(function(){
      if( $('li.panel.active').index() == lis_count-1 )
        active_li_index  = 0;
      else
        active_li_index++;
        
      $('li.panel.active').removeClass('active');
      $('li.panel').eq(active_li_index).addClass('active');
   }, 1000);
})
.active{
   background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
   <li class="panel active">Item 1</li>
   <li class="panel">Item 2</li>
   <li class="panel">Item 3</li>
 </ul>

Pure JS solution:

document.addEventListener('DOMContentLoaded', function(){ 
   var lis = Array.prototype.slice.call( document.querySelectorAll('li.panel'));
   var lis_count = lis.length;
   var active_li_index = 0;
   
   setInterval(function(){
      var active_li = document.querySelector('li.panel.active');
      
      if( lis.indexOf(active_li) == lis_count-1 )
        active_li_index  = 0;
      else
        active_li_index++;
        
      active_li.classList.remove('active');
      document.querySelectorAll('li.panel')[active_li_index].classList.add('active');
   }, 1000);
}, false);
.active{
   background-color: yellow;
}
<ul>
   <li class="panel active">Item 1</li>
   <li class="panel">Item 2</li>
   <li class="panel">Item 3</li>
 </ul>

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

3 Comments

It's exactly what I try to do but in Javascript (the jQuery tag was a mistake), but I'll keep this snippet just in case :) Thanks
You're welcome, glad i could helps. I've just added the pure js solution.
Works like a charm! Il will keep this snippet - Next step : receive javascript training :) Thanks again!
1

Without jQuery:

function showGarland () {
  var itemClass   = 'panel';
  var activeClass = '--active';
  var wait        = 2000; // 2 seconds
 
  function toggleActive (element, index, maxIndex) {
    setTimeout(function(){
     element.classList.add(activeClass);
      setTimeout(function(){
        element.classList.remove(activeClass);
        if (index == maxIndex) {
          runLoop();
        }
      }, wait);
    }, wait * index);  
  }

  function runLoop () {
    var allItems = document.getElementsByClassName(itemClass);
 
    for (var index = 0; index < allItems.length; index++) {
      var element = allItems[index];
      toggleActive(element, index, allItems.length - 1);
    }
  }
  
  runLoop();
}

window.addEventListener('load', showGarland);
.--active {
  color:red;
} 
 <ul>
   <li class="panel">Item 1</li>
   <li class="panel">Item 2</li>
   <li class="panel">Item 3</li>
 </ul>

Comments

0

since you use jQuery you can do :

jQuery(() => { // callback when DOM is ready
  $('.panel1').addClass('active'); // add your class

  setTimeout(() => { // function that execute the callback after 2000ms (2s)
   $('.panel1).removeClass('active'); // remove your class active
  }, 2000);
});

you should use different class for your differents div

3 Comments

since you use jquery how do you know??
that was in the tags when I commented, but obviously edited, see revision : stackoverflow.com/posts/44655812/revisions
Thanks for your answer Epitouille ! I don't use jQuery (don't know why it was tagged so) on this project, this is why I'm looking for a vanilla JS alternative to this kind of script.
0

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- <div class="hide">
 text
</div> -->
<ul id="Items">
   <li class="panel">Item 1</li>
   <li class="panel hide">Item 2</li>
   <li class="panel hide">Item 3</li>
 </ul>
<style>

.hide{  
    visibility: hidden;
}

</style>
<script>
$(document).ready(function() {

 var listItems = $("#Items li");
// alert(listItems);
listItems.each(function(idx, li) {
    var product = $(li);	
    setInterval(function(){ 
	product.css( "visibility", "visible" );		
$(li).next().css( "visibility", "hidden" );	
$(li).prev().css( "visibility", "hidden" );		
  
}, 2000);
});
});
</script>

The above one works fine for two elements, but for the third element its showing quickly without displayinh the second element.

Comments

0

You can use something like this, you need to call toggleClass with the index you want to start, The functions addClass and removeClass supports multiple elements and multiple classes.

// Add class to element
// support multiple classes
function addClass(elements, className){
  // split classes 
  var classArray = className.split(' ');
  var els = [];
  
  // If element does not have length property
  if(elements.length == undefined)
  	els[0] = elements
  else
  	els = elements;
  
  for(e=0; e<els.length; e++){
  	var element = els[e];
    for(i=0; i<classArray.length; i++){
      if(element.className.indexOf(classArray[i])==-1){
        element.className += ' ' + classArray[i];
      }
    }
  }
}

// Remove class to element
// support multiple classes
function removeClass(elements, className){
	var classArray = className.split(' ');
  var els = [];
  
  // If elements does not have length property
  if(elements.length == undefined)
  	els[0] = elements
  else
  	els = elements;
    
  for(e=0; e<els.length; e++){
  	var element = els[e];
    for(i= 0; i<classArray.length; i++){
      element.className = element.className.replace(classArray[i], '').trim();
    }
  }
}

function toggleClass(index){	
  // get active elements and remove active class
  removeClass(document.getElementsByClassName('active'), 'active');
  
  // add class to element at index
  addClass(document.getElementsByClassName('panel')[index], 'active');
  
  // test if index should increment or reset
  if(index<document.getElementsByClassName('panel').length - 1){
  	index++;
  }else{
  	index = 0;
  }
  
  // wait 2sec until execute toggleClass again
  setTimeout(toggleClass, 2000, index);
}

toggleClass(0);
.active {
  color: green;
}
 <ul>
   <li class="panel">Item 1</li>
   <li class="panel active">Item 2</li>
   <li class="panel">Item 3</li>
 </ul>

Edit: By the way beware with method classList since you'll need to polyfill for browser compatibility

Comments

0
window.addEventListener("load",function change(i=0){
  var els=document.getElementsByClassName("panel");
  if(els[i-1]) els[i-1].classList.toggle("active");
  els[i].classList.toggle("active");
  if(i<els.length-1) setTimeout(change,2000,i+1);
});

You could use a recursive approach to iterate over the class elements slowly and toggle their active class...

2 Comments

Yep, it's the kind of approach I'm looking for. I am not sure to properly understand this syntax here but it helps me! So, if I'm correct, it says 'add a class to .panel elements until i = numbers of .panel' but I'm not sure about the (els[i-1])
@alexis wollseifen thats to unactive the previous one
0

Without jQuery:

function showGarland () {
  var itemClass   = 'panel';
  var activeClass = '--active';
  var wait        = 2000; // 2 seconds
 
  function toggleActive (element, index, maxIndex) {
    setTimeout(function(){
     element.classList.add(activeClass);
      setTimeout(function(){
        element.classList.remove(activeClass);
        if (index == maxIndex) {
          runLoop();
        }
      }, wait);
    }, wait * index);  
  }

  function runLoop () {
    var allItems = document.getElementsByClassName(itemClass);
 
    for (var index = 0; index < allItems.length; index++) {
      var element = allItems[index];
      toggleActive(element, index, allItems.length - 1);
    }
  }
  
  runLoop();
}

window.addEventListener('load', showGarland);
.--active {
  color:red;
} 
 <ul>
   <li class="panel">Item 1</li>
   <li class="panel">Item 2</li>
   <li class="panel">Item 3</li>
 </ul>

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.