Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

180
Visualizações
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
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda