找到最接近的前一个元素jQuery

时间:2011-08-10 21:54:22

标签: jquery

我想要类似于这个person的东西,除了我想要匹配的元素可能不是直接的兄弟。

如果我有这个HTML,例如,

<h3>
    <span>
        <b>Whaddup?</b>
    </span>
</h3>
<h3>
    <span>
        <b>Hello</b>
    </span>
</h3>
<div>
    <div>
        <img />
    </div>
     <span id="me"></span>
</div>
<h3>
    <span>
        <b>Goodbye</b>
    </span>
</h3>

我希望能够做到这样的事情:

var link = $("#me").closestPreviousElement("h3 span b");
console.log(link.text()); //"Hello"

在jQuery中有一种简单的方法吗?

编辑:我应该让我的规范更清晰一些。 $("#me")可能有也可能没有父div。代码不应该假设它确实如此。我不一定了解周围的元素。

5 个答案:

答案 0 :(得分:52)

var link = $("#me").closest(":has(h3 span b)").find('h3 span b');

示例: http://jsfiddle.net/e27r8/

这使用closest()[docs]方法获取具有嵌套h3 span b的第一个祖先,然后执行.find()

当然你可以有多场比赛。


否则,您正在考虑进行更直接的遍历。

var link = $("#me").closest("h3 + div").prev().find('span b');

编辑:此版本适用于您更新的HTML。

示例: http://jsfiddle.net/e27r8/2/


编辑:已更新以处理更新的问题。

var link = $("#me").closest("h3 + *").prev().find('span b');

这使得.closest()的目标元素具有通用性,因此即使没有父元素,它仍然有效。

示例: http://jsfiddle.net/e27r8/4/

答案 1 :(得分:8)

不,没有“简单”的方式。你最好的选择是做一个循环,你首先检查每个兄弟姐妹,然后移动到父节点及其所有兄弟姐妹。

您需要将选择器分成两个,1以检查当前节点是否可以是选择器中的顶级节点,以及1以检查它的后代是否匹配。

编辑:这也许是一个插件。您可以将它与任何HTML中的任何选择器一起使用:

(function($) {
    $.fn.closestPrior = function(selector) {
        selector = selector.replace(/^\s+|\s+$/g, "");
        var combinator = selector.search(/[ +~>]|$/);
        var parent = selector.substr(0, combinator);
        var children = selector.substr(combinator);
        var el = this;
        var match = $();
        while (el.length && !match.length) {
            el = el.prev();
            if (!el.length) {
                var par = el.parent();
                // Don't use the parent - you've already checked all of the previous 
                // elements in this parent, move to its previous sibling, if any.
                while (par.length && !par.prev().length) {
                    par = par.parent();
                }
                el = par.prev();
                if (!el.length) {
                    break;
                }
            }
            if (el.is(parent) && el.find(children).length) {
                match = el.find(children).last();
            }
            else if (el.find(selector).length) {
                match = el.find(selector).last();
            }
        }
        return match;
    }
})(jQuery);

答案 2 :(得分:7)

请参阅http://api.jquery.com/prev/

var link = $("#me").parent("div").prev("h3").find("b");
alert(link.text());

请参阅http://jsfiddle.net/gBwLq/

答案 3 :(得分:5)

我知道这是旧的,但是正在寻找同样的东西,最终提出了另一个简洁明了的解决方案。这是我找到下一个或上一个元素的方式,考虑到对我们正在寻找的类型的元素进行遍历:

var ClosestPrev = $( StartObject ).prevAll( '.selectorClass' ).first();
var ClosestNext = $( StartObject ).nextAll( '.selectorClass' ).first();

我不是100%确定来自nextAll / prevAll函数的集合返回的顺序,但在我的测试用例中,似乎数组是在预期的方向上。如果有人能够澄清jquery的内部结构以确保可靠性,那么可能会有所帮助。

答案 4 :(得分:1)

var link = $("#me").closest(":has(h3 span b)").find('span b').text();