检查元素是在jQuery中的另一个元素之前还是之后

检查元素是在jQuery中的另一个元素之前还是之后,jquery,dom,Jquery,Dom,让我们假设我有这个标记 <h3 id="first">First</h3> <p>Hi</p> <p>Hello</p> <h3 id="second">Second</h3> <p>Bye</p> <p>Goodbye</p> 要查看一个元素是否在另一个元素之后,可以使用或获取前面的元素,并查看它是否匹配 $.fn.isAfter = functio

让我们假设我有这个标记

<h3 id="first">First</h3>
<p>Hi</p>
<p>Hello</p>
<h3 id="second">Second</h3>
<p>Bye</p>
<p>Goodbye</p>

要查看一个元素是否在另一个元素之后,可以使用或获取前面的元素,并查看它是否匹配

$.fn.isAfter = function(sel){
  return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
  return this.nextAll(sel).length !== 0;
}
要查看一个元素是否在另一个元素之前,可以使用或获取下一个元素,并查看它是否匹配

$.fn.isAfter = function(sel){
  return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
  return this.nextAll(sel).length !== 0;
}
演示:

这是一个

您可以使用以下功能:

$('p').each(function(){
   var index = $(this).index();
   if(index > $("#first").index() && index < $("#second").index()) {
     // do stuff
   }
});
function isBeforeElement( first_id, second_id ) {
    return document.querySelectorAll('#' + first_id + ', #' + second_id)[0] === document.getElementById(first_id);
}
$('p')。每个(函数(){
var index=$(this.index();
if(index>$(“#first”).index()和&index<$(“#second”).index()){
//做事
}
});
答案是:

$.fn.isAfter = function(sel){
    return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
    return this.nextAll(sel).length !== 0;
}
正在选择所有以前的元素或下一个元素,而不考虑选择器(sel),因此我进行了以下修改,根据类选择元素:

$.fn.isAfter = function(sel){
    sel = "." + sel.attr("class").replace(/ /g, ".");

    return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
    sel = "." + sel.attr("class").replace(/ /g, ".");

    return this.nextAll(sel).length !== 0;
}

如果
sel
是一个真正的选择器,Rocket的解决方案就可以很好地工作,但是如果您传递一个jquery对象,它就不会工作

如果您想要一个可以同时使用选择器和jquery对象的插件,只需使用我稍微修改过的版本即可:

(function($) {
    $.fn.isAfter = function(sel){
        return this.prevAll().filter(sel).length !== 0;
    };

    $.fn.isBefore= function(sel){
        return this.nextAll().filter(sel).length !== 0;
    };
})(jQuery);

感谢Rocket的原始解决方案。

记住Rocket的答案,我更喜欢使用
.index()
方法,如下所示:

$.fn.isAfter = function(sel){
    return $(this).index() > $(sel).index();
};
$.fn.isBefore= function(sel){
    return $(this).index() < $(sel).index();
};
$.fn.isAfter=函数(sel){
返回$(this.index()>$(sel.index());
};
$.fn.isBefore=函数(sel){
返回$(this.index()<$(sel.index());
};

似乎更清楚地阅读/理解并在行选择中完美地工作。

如果前面提到的元素是兄弟姐妹(它们是原来的问题),那么前面的答案就很好,但是更一般的解决方案会考虑下面的场景:

<div id="top">    
    <div>
        <div>
           <h3 id="first">First</h3>
           <p>Hi</p>
           <p>Hello</p>
        </div>
    </div>
    <div>
        <h3 id="second">Second</h3>
        <p>Bye</p>
        <p>Goodbye</p>
    </div>
</div>

当然,所有这些都假设“before”和“after”表示它们在文档模型中的顺序。如果您关心元素在显示器上的相对位置,您可能希望检查元素相对于文档的显示坐标,如“相对”、“固定”和“绝对”CSS位置。我实现了一个通用的
isAfter
功能,它考虑了深度和DOM树,可以正确确定
a
是否在
b
之后,即使它们位于两个不同的子树中:


我先来

我得了第二名


你可以在一本书中找到它。非常感谢您对代码的反馈

只有当元素处于同一级别时,接受的答案才有效。如果要定位哪个元素是第一个,而不考虑级别,则解决该问题的一种方法是:

  • 为具有相同值的每个元素设置临时属性
  • 使用jquery选择器查找具有该属性值的第一个元素

  • 如果两个元素在彼此之前、相等或之后,此版本可以在任何深度进行比较。分别返回-1、0和1

    它的工作原理是获取传递到compare函数的元素的所有索引偏移量

    然后比较两个偏移量数组,并在发现差异时停止迭代

    var-topElement=$(“span”).eq(0);
    var bottomElement=$(“span”)。等式(2);
    var res=比较(topElement,bottomElement);
    log(“比较结果为:“+res”)
    函数getOffsets(el)
    {
    var res=新数组();
    而(el.length>0)
    {
    res.push(el.index());
    el=el.parent();
    }
    return res.reverse();
    }
    功能比较(a、b)
    {  
    var offA=获得补偿(a);
    var offB=获得补偿(b);
    for(设i=0;i0)
    返回1;
    }
    返回0;
    }
    
    1.
    2.
    3.
    
    这种一行检查在任何情况下都有效 用于此示例的问题ID:

    document.getElementById("first") === document.querySelectorAll("#second, #first")[0]
    
    querySelectorAll
    方法中ID的顺序不相关。在这种情况下,只需要使用选择器来选择两个元素,即
    #秒、#首

    如果需要多次使用此功能,可以使用此功能:

    $('p').each(function(){
       var index = $(this).index();
       if(index > $("#first").index() && index < $("#second").index()) {
         // do stuff
       }
    });
    
    function isBeforeElement( first_id, second_id ) {
        return document.querySelectorAll('#' + first_id + ', #' + second_id)[0] === document.getElementById(first_id);
    }
    
    即使在特殊情况下,此功能也能正常工作:

  • 如果两个元素都未找到,它将返回
    false
  • 如果未找到second元素,它将返回
    true
  • 如果未找到第一个元素,它将返回
    false

  • 你是在问它是直接在兄弟姐妹之间还是在兄弟姐妹之间?@Amin在兄弟姐妹之间!回答正确。通过测试,包括将选择器与自身进行比较:这是最好的方法+1只有在元素处于相同级别时才能工作Boo,回答错误!导致误报/不支持jQuery结果数组。请看,请改用Marco的答案。另外,请看一下使用元素的.index()来比较其位置的方法。对我来说,这似乎更具可读性:)有趣,但请记住,如果选择器与DOM元素不匹配,
    index
    函数将返回-1。
    function isBeforeElement( first_id, second_id ) {
        return document.querySelectorAll('#' + first_id + ', #' + second_id)[0] === document.getElementById(first_id);
    }