2

I am making a sort of a progressbar / navigation element that shows the page you are currently at and pages you have visited. There's an extra feature of changing the color of a page you have already visited but that is actually "further" than you current one (for example: you have read first 16 pages, you navigate back to back 8, pages 9 to 16 show with different color).

My implementation works fine if you just navigate forwards and backwards without skipping. Problems start when you skip to a page. When you navigate backwards from there, the additional class visited_page_gt_current doesn't get applied even when it should. When you navigate backwards enough one by one, at certain point the pages that didn't previously change color change to the correct color (multiple ones at a time).

The code to change the classes:

 // remove current page and visited_page_gt_current from all the visited ones to be sure
    $(".visited_page").removeClass("current_page visited_page_gt_current");

 // add current page and visited page classes to the current element
    $("#pbar_elem"+i).addClass("current_page visited_page");

 //add visited_page_gt_current to all visited pages that are "further" than the current page
    $(".visited_page").slice(i-1, 15).addClass("visited_page_gt_current");

I made a simplified JSFiddle to demonstrate the problem: http://jsfiddle.net/eQY3h/30/

Things I have tried:

  • using different methods to get the div's I need to change color of: slicing, using :gt()-selector, taking the ID's and using first() & :not('.visited_page') to get the div's that are .visited_pages after the first unvisited one.

  • all of the above work the similar way but all fail after skipping: the selectors just give empty results after skipping until a certain point comes and they give the correct ID's again

2
  • 1
    the problem lies within the application of the slice method. You select only the elements you visited before $(".visited_pages") and you then slice at position i-1, but there are less then 15 elements in the result set.. Commented Dec 12, 2013 at 13:10
  • Correct me if i'm wrong, but $(".visited_page").slice(i-1, 15).addClass("visited_page_gt_current"); will only handle items that have the class 'visited_page', and the items that are not clicked don't Commented Dec 12, 2013 at 13:11

1 Answer 1

3

The problem is that the .slice idea is wrong. It should not be applied to .visited_page but rather to all pages; filter on .visited_page after slicing. So this would work:

$(".pbar_elem").slice(i - 1)
    .filter(".visited_page").addClass("visited_page_gt_current");

An alternative equivalent version is to do this instead:

$("#pbar_holder"+i).nextAll()
    .find(".visited_page").addClass("visited_page_gt_current");
Sign up to request clarification or add additional context in comments.

2 Comments

The first one solved my problem, thank you. Any idea why it works as it should if you just pick them one by one?
@PeteTNT: Because if the results of the slice are all visited as well the order of slicing and filtering does not matter (same result either way). But if the results of slicing are not all visited then order matters.

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.