我已经编写了一个非常简单的 jQuery 插件来在客户端对一个ul
或多个ol
元素进行切片,但是我在多个元素上启动它时目睹了非常奇怪的行为。该插件基本上隐藏了列表中的额外项目,只显示指定数量的项目。它将更多/更少链接附加到列表中,以便用户可以切换项目。以下是插件的代码。
/**
* jQuery list slice v1.0
*
* Slices a list ('ul', 'ol') and shows a more/less link to either show more
* or less 'li's respectively.
*
* @USAGE:
* For a list like the following:
*
* <ul id="sample-list">
* <li>Item 1</li>
* <li>Item 2</li>
* <li>Item 3</li>
* </ul>
*
* Initiate the sliceList as follows:
*
* $('ul.sample-list').listSlice({
* default_items: 2, // Set Any other options here
* });
*/
(function($) {
$.fn.listSlice = function(options) {
// Merge or Override user defined options
options = $.extend({}, $.fn.listSlice.options, options);
var entity = $(this);
/**
* Slices the initiating list to show the number of default_items
* and append a more link to the list.
*/
function sliceList(){
entity.find('li').addClass('listSliceItem');
// Make sure we do not count items in ignore_list
ignore_list = options.ignore_list.split(',');
$.each(ignore_list, function() {
var class_name = '.' + $.trim(this);
var id_name = '#' + $.trim(this);
var obj = entity.find(class_name);
obj.removeClass('listSliceItem');
if (!(obj.is('li'))) {
obj.closest('li').removeClass('listSliceItem');
}
var obj = entity.find(id_name);
obj.removeClass('listSliceItem');
if (!(obj.is('li'))) {
obj.closest('li').removeClass('listSliceItem');
}
});
$.each(entity, function() {
var current_entity = $(this);
var should_apply = true;
if((current_entity.find('li.listSliceItem').length) <= (
options.default_items)) {
should_apply = false;
}
// Make sure we apply more/less only to lists that have
// enough 'li' elements.
if(should_apply) {
current_entity.find('li.listSliceItem' +
':gt(' + (options.default_items - 1).toString() +
')').hide();
current_entity.append('<' + options.link_container +
' class="' + options.link_container_class + '">' +
'<a href="#!" class="listSliceMore ' +
options.link_class + '">' + options.more_text + '</a>');
}
});
}
/**
* uses the slideToggle method to toggle between showing more or less
* list items in the initiated list.
*/
function toggleMoreLess(btn){
var dad = btn.parent().parent();
dad.find('li.listSliceItem' +
':gt(' + (options.default_items - 1).toString() +
')').slideToggle(options.animation_time);
btn.text(btn.text() == options.more_text ? options.less_text : options.more_text);
}
/**
* Initiate the sliceList method and more link click method.
*/
sliceList();
$('a.listSliceMore').click( function() {
toggleMoreLess($(this));
return false; // Cancel Default Anchor Action.
// This prevents appending '#!' to the end of the url
});
}
// Default options
$.fn.listSlice.options = {
// Default number of items to be displayed (Accepts Integer only).
default_items: 5,
// More Anchor link's label when hiding items (Accepts Strings only).
more_text: 'More',
// More Anchor link's label when showing all items (Accepts Strings only).
less_text: 'Less',
// Class names to be applied to the More link (Accepts Strings only).
link_class: 'more link',
// Class names to be applied to the More link's container (Accepts Strings only).
link_container_class: 'more',
// An element that wraps the more link. (Accepts Strings only)
link_container: 'li',
// Amount of time in miliseconds the show/hide animation should run.(Accepts Integer and Strings)
animation_time: 500,
// Ignore 'li' items to be counted as the part of list which have following classes
// or id's. A comma separated list of classes or id's or both. (Accepts Strings Only)
ignore_list: 'ignore, no-include, all',
}
})(jQuery);
现在,这是场景。假设我的 HTML 格式如下:
<div id ="one">
<ul class="item_list">
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
</ul>
</div>
<div id ="two">
<ul class="item_list">
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
</ul>
</div>
<div id ="three">
<ul class="item_list">
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
</ul>
</div>
<div id ="four">
<ul class="item_list">
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
<li> Sample Item </li>
</ul>
</div>
我启动我的插件如下:
<script type="text/javascript">
$('.item_list').listSlice();
</script>
它工作得很好。但是假设我想为以上四个元素设置不同的选项,我将它们分别绑定如下。
<script type="text/javascript">
$('div#one .item_list').listSlice({
some_option: some_value,
});
$('div#two .item_list').listSlice({
some_option: some_value,
});
$('div#three .item_list').listSlice({
some_option: some_value,
});
$('div#four .item_list').listSlice({
some_option: some_value,
});
</script>
这是它变得有点混乱的时候。我在这里看到的行为是:
如果我单击
more/less
第一个列表的链接,Click 会被触发 4 次,因此动画会上下滑动 4 次。如果我点击第二个列表的更多/更少链接,点击会被触发 3 次。
如果我点击第三个列表的更多/更少链接,点击会被触发 2 次。
如果我单击第四个列表的更多/更少链接,它工作正常。(即点击仅被触发1次)
这是一个显示我面临的问题的jsfiddle 。
有人知道是什么原因造成的吗?谢谢。