Javascript 使用jQuery查找DOM中最近的下一个元素

Javascript 使用jQuery查找DOM中最近的下一个元素,javascript,jquery,dom,jquery-traversing,Javascript,Jquery,Dom,Jquery Traversing,在下面的示例中。我想找到第一个。无效反馈和。两个项目的有效反馈。\main和\secondary 显然,我对泛型案例感兴趣,这就是我为jQuery编写原型扩展的原因 $.fn.extend({ 关闭下一步:功能(选择器){ let found=null 让搜索=(el,选择器)=>{ 如果(!el.length)返回 if(标高下一高度(选择器).长度){ found=el.nextAll(选择器).first() 返回 } 搜索(el.parent(),选择器) } 搜索($(此),选择器)

在下面的示例中。我想找到第一个
。无效反馈
。两个项目的有效反馈
\main
\secondary

显然,我对泛型案例感兴趣,这就是我为jQuery编写原型扩展的原因

$.fn.extend({
关闭下一步:功能(选择器){
let found=null
让搜索=(el,选择器)=>{
如果(!el.length)返回
if(标高下一高度(选择器).长度){
found=el.nextAll(选择器).first()
返回
}
搜索(el.parent(),选择器)
}
搜索($(此),选择器)
返回发现
}
})
//证明
$(“#main”).closestNext(“.invalid feedback”).text('main-invalid'))
$('#secondary').ClosesNext('.invalid feedback').text('secondary-invalid'))
$(“#main”).closestNext(“.valid feedback”).text('any-valid')

我还没有机会运行这个程序(编辑:它已经运行了,并且已经进行了更正),但是这样做就可以了。我们有两个函数-第一个函数查找与我们正在搜索的目标节点匹配的元素的同级。第二个函数将使球滚动,并在GetSides未返回目标元素的匹配项时向上提升节点树。 我希望这有帮助。。享受



var getSiblings = function (elem,selector) {

    // Setup siblings array and start from the parent element of our input
    //this is under the assumption that you're only looking for an element that FOLLOWS #main/#secondary


    var sibling = elem,
    target = selector;

    // Loop through each sibling and return the target element if its found
    while (sibling) {

            if (sibling.hasClass(target) ) { //return the target element if its been located
                return sibling;
            }
        //since the element has not been located, move onto the next sibling
        if (sibling.next().length == 0) {
            return 0;
        } else {
            sibling = sibling.next();
        }

    }

    return 0; //failed to locate target
};

function firstOfClass(el,selector) {
   //our variables where startingPoint is #main/#secondary and target is what we're looking for
   var startingPoint = el,
   target = selector;
   while (startingPoint.parent().length) { 
//if it has a parent lets take a look using our getSiblings function
       var targetCheck = getSiblings(startingPoint, target);
       if ( targetCheck != 0 ) { //returns 0 if no siblings are found i.e we found a match
           return targetCheck;
       } else {
//lets keep ascending
           startingPoint = startingPoint.parent();
       }
   }
   return getSiblings(startingPoint, target);

}
//returns node if found, otherwise returns 0

firstOfClass( $('#main'),'valid-feedback' );

firstOfClass( $('#secondary'),'invalid-feedback' );

正如您所见,解决方案不需要对DOM有任何深入的了解,而是系统地搜索目标(除非找到目标,否则它将停止运行),并继续上升,直到它有效地完成搜索。

不确定这是否完全可行,但我认为是这样,这在某种程度上取决于您的标记有多复杂,但即使这样,我认为它也会给你下一次出现的有效或无效的反馈类,这些反馈类与所讨论的元素相关,因为你的id是唯一的,匹配集中的索引+1应该是你要寻找的。可能是杀伤力过大,但它应该得到DOM树中下一个最近的一个,而不仅仅是兄弟姐妹、孩子等等。我加入CSS更改以验证它正在做什么

$("#main, #secondary").on("click", function(e) {
  var invalid = $(this).add('.invalid-feedback');
  var valid = $(this).add('.valid-feedback');
  $(invalid.get(invalid.index( $(this)) +1)).css("background", "black");
  $(valid.get(valid.index( $(this)) +1)).css("background", "blue");
});

这样可以,但绝对不干净。我必须确保“以前”的节点不包括在内,所以我过滤掉它们

我又添加了几个测试用例来证明它只对“下一个”项目起作用

我同意你现有的解决方案

$.fn.extend({
关闭下一步:功能(选择器、原始名称){
const me=$(此);
//先试试下一个
让nextSibling=me.next(选择器);
if(nextSibling.length)返回nextSibling;
//试一试后代
让后代=me.find(selector).not((i,e)=>(originalMe | | me.prevAll().is(e));
if(degents.length)返回degents.first();
//试试下一个家长
const parent=me.parent().not((i,e)=>(originalMe | | me.parent().prevAll().is(e));
返回parent.closestNext(选择器,me);
}
})
//证明
$(“#main”).closestNext(“.invalid feedback”).text('main-invalid'))
$('#secondary').ClosesNext('.invalid feedback').text('secondary-invalid'))
$(“#main”).closestNext(“.valid feedback”).text('any-valid')
.dummy{
颜色:红色;
}

不应该改变
不应该改变
不应该改变
应该改变
应该改变

应该更改
我看不出初始代码如何更简单。毕竟,它需要迭代标记

但是我看到的是如何优化它,使用
return
支持
let found=null
并且只调用
el.nextAll(选择器)
一次

我还讨论了找不到元素的情况,如果找不到,则会出现异常

堆栈片段

$.fn.extend({
关闭下一步:功能(选择器){
让搜索=(el,选择器)=>{
如果(!el.length)返回el
设f=el.nextAll(选择器)
返回f.length?f.first():搜索(el.parent(),选择器)
}
返回搜索($(此),选择器)
}
})
//证明
$(“#main”).closestNext(“.invalid feedback”).text('main-invalid'))
$('#secondary').ClosesNext('.invalid feedback').text('secondary-invalid'))
$(“#main”).closestNext(“.valid feedback”).text('any-valid')


您知道html结构吗?预期响应?@NagaSaiA给定示例的预期响应在我的问题中。如果答案(以及您对删除的答案的评论)您可能需要澄清标记深度未知。@Hereticsmonkey简单地说,OP不知道下一个是从哪个ascendent找到的。好吧,看起来你的解决方案比我的稍微麻烦一些:)注意,如果没有找到元素,例如第一个
。无效反馈
,你的代码会得到一个奇怪的结果。我发布了一个简化的版本的原始,地址是。