简体   繁体   中英

Previous occurrence of element in DOM using JQuery selector

I'm wondering how to get the previous occurrence of a selector from an element regardless of where it is in the DOM tree. I'm assuming that the previous occurrence is not one of my original element's children.

Example:

<body>
    <p class="somethingImportant">Important</p>
    <h1>
        <p class="somethingImportant">Important too!</p>
    </h1>

    <table>
        <tr>
            <td id="start">Starting from here!</td>
        </tr>
    </table>
</body>

I want to get the <p class="somethingImportant">Important too!</p> element, starting from the <td id="start"> element.

I've tried using the prev() and next() in JQuery, but they only get immediate siblings. I tried the closest() one too, but that only gets ancestors. Notice how the element I want is a child of an ancestor.

So, I tried something like $("#start").closest(".somethingImportant").find(".somethingImportant") and JQuery didn't return any results, mainly because closest() didn't I guess.

I want something like prevAll(".somethingImportant").last() , just without the immediate sibling limitation.

Has anyone else ran into this problem?


EDIT

The problem I'm trying to solve is how to get the previous "page" or the previous "heading" from a start element. The start element is a "cursor" that highlights the node I'm on. I'll have the view scroll to that element later in my code.

Here is a situation that it starts becoming a problem:

<p class="pageNumber">1</p>

<h1>Kinds of Animals</h1>

<p>Here are different kinds of animals:</p>

<table>
    <tr><td>Duck</td><td>Giraffe</td></tr>
    <tr><td>Anteater</td><td><span id="highlight">Badger</span></td></tr>
</table

I'm starting from `<span id="highlight"> . I want to get the previous element that matches the JQuery selector p.pageNumber, h1, h2, h3, h4, h5, h6 no matter where it is nested in the DOM, as long as it's before the highlight. The selector matches all of the elements that I recognize as heading elements.

In this case, it should return <h1>Kinds of Animals</h1> .


Code Samples

Using Lee's solution, I was able to build a function that does a pretty good, yet elegant job of what I wanted it to do.

function GetPreviousOccurrence(elemSel, sel) {
    var selector = elemSel + ", " + sel;
    var prev;
    $(selector).each(function() {
        if ($(this).is(elemSel)) {
            return false;
        }
        prev = this;
    });

    return prev;
}

In my case, elemSel = "#highlight"; and sel = "p.pageNumber, h1, h2, h3, h4, h5 , h6"; It might not be super performant, but at least it reads nice.

Extra Note: Lee's addendum is better.

This will get a list of the DOM elements including those among which you want to find previous and the one you mention. I'm assuming you change the funky <p> elements to <div> and the id becomes a class:

var prev;
$(".start, .somethingImportant").each(function () {
    if ($(this).hasClass("start")) {
        return false;
    }
    prev = this;
});

... now '$(prev)' contains the previous elemnent you wanted 
...  or 'undefined' if there are none.

You get all the elements. jQuery does it in DOM order. Iterate through and when you find the 'start' element, the previous one is the one you wanted.

FIDDLE

Note that with your example, this would work since there are no 'important' elements after the start element:

$(".somethingImportant:last")

Addendum

Another thought I had based on OP's solution function.

// Call this way
var $prev = GetPreviousOccurrence($("#highlight"), $("p.pageNumber, h1, h2, h3, h4, h5 , h6"));


function GetPreviousOccurrence($elemSel, $sel) {
    var selector = $elemSel.add($sel);
    var $prev;
    $(selector).each(function() {
        if ($(this).is($elemSel)) {
            return false;
        }
        $prev = $(this);
    });

    return $prev;
}

ANOTHER FIDDLE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM