开发者

How can I apply truncate/hide list items from multiple lists on a page?

I have this handy snippet [see below] that truncates a set of list items to a given amount using jQuery. However, I'm stuck on how to modify this script to work on multiple lists on a page. Can you help?

Assume I have 5 lists of 100 items on a page. How can I dynamically hide various amounts of list items in each list?

Here's how it currently works (with one list per 开发者_如何学运维page):

<script>
function ShowItems() {
    if (Count > $("ul.truncateList > li").size()) { Count = $("ul.truncateList > li").size() };
    $("ul.truncateList > li:lt(" + Count + ")").show();
    $("ul.truncateList > li:gt(" + (Count - 1) + ")").hide();
}

(function($){
    var listItems = $('ul.truncateList').data('listItems');
    Count= listItems;
    ShowItems();
    $('.listHide').toggle();
    $('.listShow').click(function(){
        Count = 100000;
        ShowItems();
        $('.listShow').toggle();
        $('.listHide').toggle();
    });
    $('.listHide').click(function(){
        Count = listItems;
        ShowItems();
        $('.listShow').toggle();
        $('.listHide').toggle();
    });

})(jQuery);
</script>

Usage:

<ul class="truncateList" data-listItems="25">
    <li>One</li>
    ....
    <li>Twenty Six</li>
</ul>
<span class="listShow">View All</span>
<span class="listHide">View Less</span>

The Twenty Sixth list item (and greater) will be hidden until "View All" is clicked. But if I put a second list on the same page with the class "truncateList", it won't work.

I'm definitely open to more elegant solutions to the whole challenge of visually hiding long lists until a user wants to read more (100% client-side).


For multiple lists, eack with it's own "show / hide", merge those 2 spans and put a control after each list like so:

<ul class="truncateList" data-list-items="2">
    <li>One</li>
    ...
</ul>
<button class="ShowHideFullLists" type="button">View All</button>

<h2>Second list:</h2>
<ul class="truncateList" data-list-items="4">
    <li>A 1</li>
    ...
</ul>
<button class="ShowHideFullLists" type="button">View All</button>


Then the following code will work.  See it in action at jsFiddle.

$('.ShowHideFullLists').click (ShowHideFullLists);
$('.ShowHideFullLists').click ();  //-- Init list displays.

function ShowHideFullLists () {
    var showHideBtn = $(this);
    var bShowEm     = showHideBtn.data ('bShowEm')  ||  false;

    /*--- Find the list for this button. It is a previous sibling,
        in the HTML.
    */
    var thisBtnsList    = showHideBtn.prev ("ul.truncateList");

    //--- Show either all or the # from the data-list-items attribute.
    ShowItems (thisBtnsList, bShowEm, thisBtnsList.data('listItems'));

    //--- Update the show-all flag.
    bShowEm ^= true;
    showHideBtn.data ('bShowEm', bShowEm);

    //--- Update the button text.
    if (bShowEm)
        showHideBtn.text ('View All');
    else
        showHideBtn.text ('View Less');
}

function ShowItems (parentNode, bShowAll, numVisible) {

    if (bShowAll)
        parentNode.find ("> li").show ();
    else {
        parentNode.find ("> li:lt(" +  numVisible    + ")").show ();
        parentNode.find ("> li:gt(" + (numVisible-1) + ")").hide ();
    }
}




For one button to control all lists...

Then ShowHideFullLists changes as follows. See that in action at jsFiddle. :

ShowHideFullLists ();   //-- Init list displays.

//--- Activate the show/hide button.
$('#ShowHideFullLists').click (ShowHideFullLists);

function ShowHideFullLists () {
    var showHideBtn = $('#ShowHideFullLists');
    var bShowEm     = showHideBtn.data ('bShowEm')  ||  false;

    //--- Loop through all the different lists.
    $("ul.truncateList").each ( function () {
        /*--- Show all or the number defined in the 
            data-list-items attribute.
        */
        if (bShowEm)
            ShowItems ( $(this), true);
        else {
            var jThis   = $(this);
            ShowItems (jThis, false, jThis.data ('listItems') );
        }
    } );

    //--- Update the show-all flag.
    bShowEm ^= true;
    showHideBtn.data ('bShowEm', bShowEm);

    //--- Update the button text.
    if (bShowEm)
        showHideBtn.text ('View All');
    else
        showHideBtn.text ('View Less');
}


Also, note the case-sensitivity and dash-refactoring of HTML 5 data- attributes.


I would wrap my lists into parent divs

<div class="truncateList">
  <ul data-listItems="2">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
  <span class="listshow">View All</span>
  <span class="listhide">View Less</span>
</div>
<div class="truncateList">
  <ul data-listItems="3">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
  <span class="listshow">View All</span>
  <span class="listhide">View Less</span>
</div>

And then with this code, properly hide items on load

$(".truncateList").each(function(e){
  var list = $("ul", this);
  var count = list.data("listitems") - 1;
  $("li:gt(" + count + ")", list).hide();
});

And hook the click events to show/hide the lists

$(".listshow").click(function(e){
  var list = $("ul", $(this).parent());
  var count = list.data("listitems") - 1;
  $("li", list).show();
});

$(".listhide").click(function(e){
  var list = $("ul", $(this).parent());
  var count = list.data("listitems") - 1;
  $("li:gt(" + count + ")", list).hide();
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜