Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

178
Views
preceding-axis we know and love from XPath in javascript?

I am surprised there isn't some cookbook code ready that enumerates or searches along the preceding-axis in a DOM with javascript the way that XPath can do it. And of course, the following-axis as well.

Example problem is: I have a text node, and I want to find the preceding text node.

Obviously the precedingSibling is insufficient, because there could be none, or it could be an element.

I have implemented that several times for myself, but am too lazy to try to find my code. Instead I prefer doing it over again. But also like to compare notes, and surprised that nobody seems to ask about it, or show off theirs.

So here is a function signature with some beginning scribble:

Node.prototype.findPrevious function(foundPr = x => x, giveUpPr = () => false) {
    node = this;
    while(true) {
        let previousSibling = node.previousSibling;
        if(!previousSibling) // no previousSibling means we need to go up
            while(true) {
                const parent = node.parentNode;
                previousSibling = parent.previousSibling;
                if(parent.previousSibling)
                    break;
                node = parent;
                if(!node || giveUpPr(node))
                    return null;
            }
        // now we have the nearest previous sibling (or we gave up already)
        node = previousSibling;
        // but we aren't done, we have to go down now
        // now finally we have the last previous item
        while(true) {
            let lastChild = node.lastChild;
            if(!lastChild)
                break;
            node = lastChild;
        }
        // now our node is the deepest lastChild that doesn't have any more children
        // now only can we check our found predicate:
        if(foundPr(node))
            return node;
        // and if not we go to the beginning
    }
};

I guess I just wrote the code instead of explaining what it would do. And the cool thing is that the same logic works the other way around for findNext:

Node.prototype.findNext = function(foundPr = x => x, giveUpPr = () => false) {
    let node = this;
    while(true) {
        let nextSibling = node.nextSibling;
        if(!nextSibling) // no nextSibling means we need to go up
            while(true) {
                const parent = node.parentNode;
                nextSibling = parent.nextSibling;
                if(nextSibling)
                    break;
                node = parent;
                if(!node || giveUpPr(node))
                    return null;
            }
        // now we have the nearest next sibling (or we gave up already)
        node = nextSibling;
        // but we aren't done, we have to go down now
        // now finally we have the first next item
        while(true) {
            let firstChild = node.firstChild;
            if(!firstChild)
                break;
            node = firstChild;
        }
        // now our node is the deepest firstChild that doesn't have any more children
        // now only can we check our found predicate:
        if(foundPr(node))
            return node;
        // and if not we go to the beginning trying the nextSibling
    }
};

But isn't there some built-in solution already?

about 4 years ago · Santiago Gelvez
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!