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();
});
精彩评论