是否可以让.nextUntil()在拆分列表上工作,或者获得相同的功能?
所以我正在尝试为我的项目实现如此受欢迎的班次选择,并且由于它们在我的应用程序的列表中排序,我希望能够跨<ul>
个边框进行选择。
我有以下DOM元素集:
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
使用类似的东西:
$('li.clicked').nextUntil('li.selected');
我喜欢包含以下元素的列表
[ <li class="item">third</li>,
<li class="item">fourth</li>,
<li class="item">fifth</li> ]
然而,我得到的只是导致分割</ul>
的元素。有没有办法做到这一点?我还尝试先使用$('.item')
选择所有项目,然后使用.nextUntil()
,但没有任何运气。
答案 0 :(得分:2)
这是你在找什么?
$('li').slice($('li').index($('.clicked'))+1,$('li').index($('.selected')));
供参考
修改强>
所以,如果你这样做
$('li')
你将获得所有元素'li'获得的数组:
[<li class="item">first</li>,
<li class="item clicked">second</li>,
<li class="item">third</li>,
<li class="item">fourth</li>,
<li class="item">fifth</li>,
<li class="item selected">sixth</li>,
<li class="item">seventh</li>]
因为它是一个数组你可以切片他得到一个子数组你只需要两个位置,从哪里开始到这里完成。
//start
$('li').index($('.clicked'))+1 // +1 because you dont want to select him self
//end
$('li').index($('.selected'))
为了获得更好的性能,你应该在创建一个包含所有li的数组之前,这样就不会在'li'数组中搜索所有dom 3次
var array = $('li');
var subarray = array.slice(array.index($('.clicked'))+1,array.index($('.selected')));
答案 1 :(得分:2)
假设这些列表无法合并为一个,则无法使用nextUntil
方法。这是因为jQuery如何执行遍历。根据文件,
获取每个元素的所有兄弟姐妹,但不包括由传递的选择器,DOM节点或jQuery对象匹配的元素。
fifth
不是clicked
元素的兄弟,而是元素父母兄弟的孩子。
我提出了两种可能的解决方案。
解决方案1:结合NEXT和PREV遍历
假设.clicked
始终位于第一个列表中且.selected
始终位于第二个列表中,则prevAll()
与nextAll()
的组合应该可以解决问题。这假定订单是相同的。
var siblings = $("li.clicked").nextAll()
在元素本身之后获取当前元素的所有兄弟。
var distantSiblings = $("li.selected").prevAll();
在第一个元素之后但在第二个元素之前获取所有远程兄弟姐妹。
siblings.push(distantSiblings);
将它们组合成两个,然后遍历每个元素。
var siblings = $("li.clicked").nextAll()
var distantSiblings = $("li.selected").prevAll();
siblings.push(distantSiblings);
siblings.each(function() {
$(this).addClass("blue");
});
.blue { color: blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
注意:强>
您会注意到上面的代码有效,但它可能不是最佳解决方案。这仅适用于上述示例。可能还有一个不太冗长的解决方案。
解决方案2(查找所有列表项的索引)
另一个想法是找到所有项目的索引,并收集夹在这两个索引之间的元素。然后,您将需要使用“切片”选择器来获取它们之间的范围。
var items = $(".item");
var clicked = $(".clicked");
var selected = $(".selected");
var clickIndex = items.index(clicked);
var selectIndex = items.index(selected);
$("li").slice(clickIndex + 1, selectIndex).addClass("blue");
var clicked = $(".clicked");
var selected = $(".selected");
var clickIndex = $("li").index(clicked);
var selectIndex = $("li").index(selected);
$("li").slice(clickIndex+1, selectIndex).addClass("blue");
.blue { color: blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
答案 2 :(得分:0)
您可以通过一次选择所有这些项目并使用循环来手动完成。
考虑父元素,让我们说&#34;容器&#34;:
<div id="container">
<ul class="current">
<li class="item">first</li>
<li class="item clicked">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
</div>
现在,您可以选择所有这些项目:
var $items = $("#container > ul > li.item"); // or simply $("#container .item");
迭代它们:
var $items = $(".item"), $result = $(), found = false;
for (var i = 0; i < $items.length; i++)
{
$currentItem = $items.eq(i);
if ($currentItem.is('.clicked')) {
found = true;
continue;
}
if ($currentItem.is('.selected'))
break;
if (found)
$result = $result.add($currentItem);
}
console.log($result);
这是工作JSFiddle demo。
答案 3 :(得分:0)
在任何情况下,您都需要定义li组。
我认为最简单的方法是创建一个函数来获取lis列表,你可以按照你想要的方式请求,然后过滤你感兴趣的el。
function elRange(elList, start, end){
// we do not use indexOf directly as elList is likely to be a node list
// and not an array.
var startI = [].indexOf.call(elList, start);
var endI = [].indexOf.call(elList, end);
return [].slice.call(elList, startI, endI + 1);
}
// request the group of *ordered* elements that can be selected
var liList = document.querySelectorAll('ul.current > li, ul.later > li');
var selectionEnd = document.querySelector('.selected');
[].forEach.call(liList, function(li){
li.addEventListener('click', function(){
var selected = elRange(liList, li, selectionEnd);
selected.forEach(function(el){
el.classList.add('red');
})
});
});
&#13;
.selected {
color: blue;
}
.red {
color: red;
}
&#13;
<ul class="current">
<li class="item">first</li>
<li class="item">second</li>
<li class="item">third</li>
<li class="item">fourth</li>
</ul>
<ul class="later">
<li class="item">fifth</li>
<li class="item selected">sixth</li>
<li class="item">seventh</li>
</ul>
&#13;