我需要帮助。我对jQuery' nextUntil()
方法有一些奇怪的问题。它没有像我期待的那样工作......
我的HTML中有两个注释标记,用于分隔我感兴趣的元素以及我想要进入jQuery集合的元素。为此,我首先找到两个注释节点,并在第一个上应用nextUntil
,将第二个作为参数提供。但是nextUntil
会返回所有后面第一条评论的孩子,似乎忽略了我传递给它的论点。
如何防止这种情况发生,并且只有之间的孩子这两条评论呢?
这是我的代码:
HTML:
<ul>
<li>1</li>
<li>2</li>
<!-- from -->
<li>3</li>
<li>4</li>
<!-- to -->
<li>5</li>
<li>6</li>
</ul>
JavaScript的:
const fromSign = 'from'
const toSign = 'to'
// filter callback - return only comment
// element with specific text
function commentWith (elm, txt) {
return elm.nodeType === 8 &&
elm.nodeValue.trim() === txt
}
// Step - 1 find comment with "from"
// text and save returned element
const $start = $('ul').contents().filter(
(idx, elm) => commentWith(elm, fromSign)
)
// Find comment with "to"
// text and save returned element
const $stop = $('ul').contents().filter(
(idx, elm) => commentWith(elm, toSign)
)
console.info($start, $stop) // So far, so good
// Step 2 - find all elements
// between "from" and "to" comments
let $inner = $start.nextUntil($stop)
// Not works - inner contains elements
// beyond "to" comment
console.log($inner)
// Step 2 again - find all elements
// between "from" and "to" comments
// with "redundant" prev/next
$inner = $start.nextUntil($stop.prev().next())
// OK, just li 3 and 4,
// but why? What am I missing?
console.log($inner)
PS:如果您使用<div class="from">
和<div class="end">
或其他元素来选择开始和结束,nextAll()
将按预期工作。但是,我想用注释标记选择....
我尝试使用prev
/ next
&#34; hacks&#34;作为替代方案(参见上面的代码),但当评论标记之前和/或之后没有元素时,它们表现不佳。
答案 0 :(得分:-1)
代码的第一个变体失败的原因是大多数jQuery方法只查看元素,而不是其他节点类型的节点。如jQuery documentation on contents
中所述:
请注意,大多数jQuery操作都不支持文本节点和注释节点。少数人会在他们的API文档页面上有明确的说明。
在您的情况下,对nextUntil
的调用只会逐步执行元素,甚至不会查看其他节点,因此它会&#34;错过&#34; $ stop 节点。
解决方法是使用index()
。当开始标记之前没有元素和/或停止标记之后没有元素时,这也可以很好地工作。如果 是一个元素节点,那么非元素节点返回的索引将是 所拥有的索引。
const fromSign = 'from'
const toSign = 'to'
// filter callback - return only comment
// element with specific text
function commentWith (elm, txt) {
return elm.nodeType === 8 &&
elm.nodeValue.trim() === txt
}
// Step - 1 find comment with "from"
// text and save returned index
const startIndex = $('ul').contents().filter(
(idx, elm) => commentWith(elm, fromSign)
).index();
// Find comment with "to"
// text and save returned index
const stopIndex = $('ul').contents().filter(
(idx, elm) => commentWith(elm, toSign)
).index();
console.log('indexes:', startIndex, stopIndex);
// Step 2 - get all child elements
// between "from" and "to" comments
let $inner = $('ul').children().slice(startIndex, stopIndex);
// Now it works - inner contains the elements between the markings
console.log('selected first and last text:', $inner.first().text(), $inner.last().text());
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>1</li>
<li>2</li>
<!-- from -->
<li>3</li>
<li>4</li>
<!-- to -->
<li>5</li>
<li>6</li>
</ul>
&#13;