简体   繁体   中英

Traversing a list with jQuery

I have a list of items that I want to traverse through from any point in any direction. I also want to loop around the list, meaning if I end up on the last list item and click on next, I want the next item to be the first item on the list. My page is simple, just an unordered list of 5 items, 2 buttons (one for previous and one for next) and a textarea that displays the results. Here is my code:

 $(function() { var prev = $("#prev"); // grabbing the prev button var next = $("#next"); // grabbing the next button var listItems = $("#listItems p"); // grabbing the p elements of the list items var results = $("#results"); // grabbing the textarea var itemText; // variable for holding the text node var selectedItem; // variable for the current selected item listItems.click(function() { // click event for any item itemText = $(this).text(); // selects the text of the clicked list item results.text(itemText); // adds text to textarea selectedItem = $(this).parent(); // sets selected item as the li element of the selected p element }); next.click(function() { // click event for next button var nextItem = selectedItem.next(); // setting the next item itemText = nextItem.children("p").text(); // grabbing the text of the next item results.text(itemText); // adds text to textarea selectedItem = nextItem; // sets next item }); prev.click(function() { // click event for the prev button var prevItem = selectedItem.prev(); // setting the prev item itemText = prevItem.children("p").text(); // grabbing the text of the prev item results.text(itemText); // adds text to textarea selectedItem = prevItem; // sets prev item }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <ul id="listItems"> <li><p>First item</p></li> <li><p>Item 2</p></li> <li><p>Item 3</p></li> <li><p>Item 4</p></li> <li><p>Last item</p></li> </ul> <button id="prev">Prev</button> <textarea name="results" id="results" cols="30" rows="1"></textarea> <button id="next">Next</button> 

As it sits, when I click on or approach the last item, pressing the next button clears the textarea and renders both buttons unresponsive. Logically, I know that there needs to be an if statement stating if the current item is the last item, then the next item has to be the first item. I just couldn't figure out how to code it. Here is the jsfiddle:

jsfiddle

Building on top of your code, you can check if the current element is the last or the first element, and put some conditions like this:

next.click (function () { // click event for next button
  var nextItem = '';
  if(selectedItem.index() == listItems.length -1 ){//if the last element
      nextItem == listItems[0];
  }else{
    nextItem = selectedItem.next(); // setting the next item
    itemText = nextItem.children("p").text(); // grabbing the text of the next item
    results.text(itemText); // adds text to textarea
    selectedItem = nextItem; // sets next item
  }
});

prev.click (function () { // click event for the prev button
  var prevItem = '';
  if(selectedItem.index() == 0 ){//if the first element
      prevItem == listItems[listItems.length-1]
  }else{
    prevItem = selectedItem.prev(); // setting the prev item
    itemText = prevItem.children("p").text(); // grabbing the text of the prev item
    results.text(itemText); // adds text to textarea
    selectedItem = prevItem; // sets prev item
  }
});

Not sure if this helps, but here is a jQuery plugin I came up with to reorder an element list starting from a supplied index:

$.fn.reorder = function(head) {
   var arr  = this;
   var rest = arr.splice(head, arr.length - head);
   return rest.concat(Array.prototype.slice.call(arr, 0));
};

// make the array start from the 3rd element
$.each(listItems.reorder(3), function() { ...

In the example, calling .reorder(3) will move all elements beyond the 3rd index to the front of the array allowing you to then iterate over your collection with $.each in the expected order.

You can use selectedItem.is(':first-child') and selectedItem.is(':last-child') selectors to find if you've reached the beginning or end of the list. Then you can select the first or last element of the list by going to the parent and finding the first/last child with selectedItem.parent().find('li:first') or selectedItem.parent().find('li:last')

$(function () {
    var prev = $("#prev");
    var next = $("#next");
    var listItems = $("#listItems p");
    var results = $("#results");
    var itemText;
    var selectedItem;

    listItems.on('click', function () {
        itemText = $(this).text();
        results.text(itemText);
        selectedItem = $(this).parent();
    });

    next.on('click', function () {
        var nextItem;
        //if i'm the last child, go to the parent and find the first child
        if (selectedItem.is(':last-child'))
            nextItem = selectedItem.parent().find('li:first');
        else
            nextItem = selectedItem.next();
        itemText = nextItem.children("p").text();
        results.text(itemText);
        selectedItem = nextItem;
    });

    prev.on('click', function () {
    var prevItem;
    //if im the first child, go to the parent to find the last
    if (selectedItem.is(':first-child'))
        prevItem = selectedItem.parent().find('li:last');
    else
        prevItem = selectedItem.prev();
    itemText = prevItem.children("p").text();
    results.text(itemText);
    selectedItem = prevItem;
  });
});
$(function () {
    var prev = $("#prev");
    var next = $("#next");
    var listItems = $("#listItems p");
    var results = $("#results");
    var itemText;
    var selectedItem;

    listItems.click (function () {
        itemText = $(this).text();
        results.text(itemText);
        selectedItem = $(this).parent();
    });

    next.click (function () {
        var nextItem = selectedItem.next();
        if(nextItem.length==0){
            nextItem = $("#listItems li").first();
        }            
        itemText = nextItem.children("p").text();
        results.text(itemText);
        selectedItem = nextItem;
    });

    prev.click (function () {
        var prevItem = selectedItem.prev();
        if(prevItem.length==0){
            prevItem = $("#listItems li").last();
        }
        itemText = prevItem.children("p").text();
        results.text(itemText);
        selectedItem = prevItem;
    });
});

When it reach to last or first make next element setting as last and first this will resolve the issue.

For next:

    if(nextItem.length==0){
        nextItem = $("#listItems li").first();
    }

For previous:

    if(prevItem.length==0){
        prevItem = $("#listItems li").last();
    }

Demo: https://jsfiddle.net/763x97qb/1/

Try utilizing id of button to cycle text next , prev

 var results = $("#results"); var items = $("#listItems li") // show first `li p` text results.text(items.eq(0).addClass("active").find("p").text()); function cycle(idx) { var active = $(".active") // cycle through `next` , `prev` `li` elements , next = active[idx]().is("*") ? active[idx]() : idx === "prev" ? active.siblings().eq(active.index("li") - 1) : active.siblings().addBack().eq(0); active.removeClass("active"); // set text of `results` with `next` , `prev` `li p` text results.text(next.addClass("active").find("p").text()); }; $("button").on("click", function(e) { cycle(this.id) }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <ul id="listItems"> <li> <p>First item</p> </li> <li> <p>Item 2</p> </li> <li> <p>Item 3</p> </li> <li> <p>Item 4</p> </li> <li> <p>Last item</p> </li> </ul> <button id="prev">Prev</button> <textarea name="results" id="results" cols="30" rows="1"></textarea> <button id="next">Next</button> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM