Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next element in *entire* document after certain element

This is a variation on a question asked so many times. Given any element, I want to be able to find any other element after it in the entire document. It can be a sibling but it could also be any other element that occurs afterward. For example, given the following markup,

<div>
    <p>Hello</p>
    <div>
        <p>Foo</p>
        <p class="bar">Bar</p>
        <p>rawr!</p>
    </div>
    <p>bop</p>
    <input/>
    <div>
        <p>Another</p>
        <div>
            <span>something</span>
            <p>deep!</p>
        </div>
    </div>
</div>
<p>last</p>

For the sake of this description, lets say the function I am looking for is called $.fn.nextInDocument. If I called:

$('.bar').nextInDocument('p'); //  <p>rawr</p>
$('.bar').nextInDocument('p').nextInDocument('p'); //  <p>bop</p>

Continuing on, it would get <p>Another</p>, then <p>deep!</p> and finally <p>last</p>.

Does something like this exist? I don't care if it is a selector or a function. I just need the functionality.

EDIT Updated the DOM structure to make it a more challenging question yet more clear for what I am looking for.

like image 737
Jeff Avatar asked Jun 29 '11 12:06

Jeff


2 Answers

How about this? It's a generic solution that uses DOM methods to traverse nodes in turn and tests each against the jQuery selector.

jsFiddle: http://jsfiddle.net/PsEdZ/3/

(function($) {
    function nextNode(node, omitChildren) {
        var sibling, parentNode;
        if (!omitChildren && node.hasChildNodes()) {
            return node.firstChild;
        } else {
            sibling = node.nextSibling;
            if (sibling) {
                return sibling;
            } else {
                parentNode = node.parentNode;
                return parentNode ? nextNode(parentNode, true) : null;
            }
        }
    }

    $.fn.nextInDocument = function(selector) {
        var node = this[0], $node;
        while ( (node = nextNode(node)) ) {
            $node = $(node);
            if ($node.is(selector)) {
                return $node;
            }
        }
        return null;
    }
})(jQuery);
like image 81
Tim Down Avatar answered Sep 26 '22 00:09

Tim Down


This should work. Not really sure it's useful, though...

;(function ($)
{
    $.fn.nextInDocument = function (s)
    {
        var self = this,
            next;
        do
        {
            next = self.nextAll(s).first();
            self = self.parent();
        }
        while (self.length && !next.length);

        return next;
    };
})(jQuery);

Demo: http://jsfiddle.net/mattball/HAFn8/

like image 21
Matt Ball Avatar answered Sep 26 '22 00:09

Matt Ball