3

I want to traverse through pages and toggle active class through them. How should I do this without using set class?

HTML

<div class="page active"></div>
<div class="set">
    <div class="page"></div>
    <div class="page"></div>
</div>
<div class="page"></div>

jQuery

$('.active').toggleClass('active').toggle().nextAll('.page').toggleClass('active');
Peyman Mohamadpour
  • 17,954
  • 24
  • 89
  • 100

3 Answers3

0

I am assuming that by "traverse" you mean you want to toggle the .page divs one by one in a certain order. If that is the case, write an algorithm that traverses a tree: given a root, toggle if it is a .page, and recursively deal with each of its children

function traverse(root){
  if(!root) return;
  if(root.hasClass('page')) root.toggle('active');
  root.children().forEach(function(child){
    traverse(child);
  });

  //lets say you want to bind to click event on every div
  $('div').click(function(){
    traverse($(this));
  });
}
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52
Chao Kong
  • 1
  • 1
0

Working fiddle

You could achieve that using indexes to get the next element in the DOM using the index of active one +1 then active it, I think the following is what you are looking for:

var getActiveIndex = function(){
    var active_index;
    $('.page').each(function(i){
        if ( $(this).hasClass('active') )
            active_index = i;
    })
    return active_index;
}

$('body').on('click', '.next', function(){
    var active_page_index = getActiveIndex(); //Get active page index
    var new_index = active_page_index+1; //Set the next page index
    var next_page = $('.page:eq('+new_index+')'); //Get the next page

    $('.page').removeClass('active');

    if(next_page.length)
      next_page.addClass('active');
    else
      $('.page:first').addClass('active');
})

I hope this helps.

var getActiveIndex = function(){
  var active_index;
  $('.page').each(function(i){
    if ( $(this).hasClass('active') )
      active_index = i;
  })
  return active_index;
}

$('body').on('click', '.next', function(){
  var active_page_index=getActiveIndex();
  var new_index = active_page_index+1;
  var next_page = $('.page:eq('+new_index+')');

  $('.page').removeClass('active');

  if(next_page.length)
    next_page.addClass('active');
  else
    $('.page:first').addClass('active');
})
.active{
  background-color: red; 
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page active">page</div>
<div class="set">
  <div class="page">- Set page</div>
  <div class="page">- Set page</div>
</div>
<div class="page">page</div>
<div class="page">page</div>
<div class="page">page</div>
<div class="set">
  <div class="page">- Set page</div>
  <div class="page">- Set page</div>
</div>
<div class="page">page</div>
<br>
<button class='next'>Active the next page</button>
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
  • Tnx for ur time and answer, but please not as I stated clearly, I dont want to jump over `page`s within `set`s. I want to traverse over ALL `page`s, whether it is in or out of a `set`. – Peyman Mohamadpour Jul 23 '16 at 09:40
  • @Trix is that not what you looking for ? – Zakaria Acharki Jul 24 '16 at 10:47
  • using index has been offered by @A. Wolff in comments, but I think this is like a work around and there should be other clear way to do this. – Peyman Mohamadpour Jul 24 '16 at 11:40
  • It's just a flash on the comment and works by click on the active link (I can't find that in your OP) what make it a little bit easy.. and it's may a workaround because jquery not offer a function that could do the trick smoothly yet, so IMO it's just the possible way to to achieve your desired result.. good luck. – Zakaria Acharki Jul 24 '16 at 11:44
0

Unfortunately we don't have a direct way to find the next non sibling element, but we can handle that situation in many ways using jquery functions. I just tried on way to achieve your goal, check out this working fiddle and let me know if you need any clarity, added some inline comments also for your understanding.

HTML:

<div class="page active">div 1</div>
<div class="page">div 2</div>
<div class="set">
    <div class="page">set 1 - div 1</div>
    <div class="page">set 1 - div 2</div>
    <div class="page">set 1 - div 3</div>
</div>
<div class="page">div 5</div>
<div class="set">
    <div class="page">set 2 - div 1</div>
    <div class="page">set 2 - div 2</div>
</div>
<div class="page">div 6</div>
<button class="next-btn">Next</button>

CSS:

.active {
  color: red;
}
.next-btn {
  cursor: pointer;
}

Javascript:

$(function() {
  $('button').click(function() {
    var elem = $(".page.active").toggleClass('active'); // current active element
    var nextElem = elem.next(); // next element

    // go above one level and get next element
    // if no next element exists, means end of the child level
    if (!nextElem.length) {
        nextElem = elem.parent().next();
    }

    // if next element has some PAGE children then update the first child element 
    if (nextElem.children('.page').length > 0 ) {
        nextElem.children('.page:first-child').toggleClass('active');
    } else if (nextElem.hasClass('page')) {
        nextElem.toggleClass('active');
    }
  });
});

This approach handles the scenario with one child level, you can extend this to multiple levels also with recursive functions, I think this helps you to handle your scenario accordingly.

Siva
  • 1,123
  • 2
  • 14
  • 25