2011-06-29 11 views
5

Esta es una variación de una pregunta que tantas veces. Dado cualquier elemento, deseo poder encontrar cualquier otro elemento después del documento entero. Puede ser un hermano, pero también podría ser cualquier otro elemento que ocurra después. Por ejemplo, dada la siguiente marcado,elemento siguiente en todo el documento * * después de cierto elemento

<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> 

En aras de esta descripción, digamos que la función Busco se llama $.fn.nextInDocument. Si llamara:

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

Continuando, se obtendría <p>Another</p>, entonces <p>deep!</p> y finalmente <p>last</p>.

¿Algo como esto existe? No me importa si es un selector o una función. Solo necesito la funcionalidad.

EDITAR Actualizado la estructura DOM para que sea una pregunta más difícil todavía más clara de lo que yo estoy buscando.

Respuesta

2

¿Qué tal esto? Es una solución genérica que utiliza métodos DOM para atravesar nodos por turnos y prueba cada uno con el selector jQuery.

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); 
+0

esto parece que funciona. probando algunas situaciones complicadas ahora ... – Jeff

+0

esto ha resistido todo lo que arrojé hasta ahora. Me pregunto qué tan bien funciona, pensé que en este momento no estoy planeando correr en páginas excesivamente grandes. ¡muchas gracias! – Jeff

+0

@Jeff: Probablemente podría optimizarse: por ejemplo, imagino que evaluar el selector para cada nodo es una causa de posibles problemas de rendimiento. Sugeriría solo molestarse en hacerlo si está causando un cuello de botella. –

1

Esto debería funcionar. No es muy seguro que es útil, aunque ...

;(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); 

Demostración: http://jsfiddle.net/mattball/HAFn8/

+0

@ Matt bola que tiene algunos problemas que entran en elementos secundarios después de un elemento de corriente, aunque no estoy seguro de si era incluso después de la funcionalidad de esa manera: http://jsfiddle.net/niklasvh/HAFn8/3/ – Niklas

+0

Gracias por señalar eso. Una deficiencia obvia, definitivamente hará las cosas más complicadas si es necesario. Necesitará un mejor algoritmo para atravesar árboles. –

+0

No estoy muy seguro de cómo funciona esto, pero parece prometedor. Lo pongo en un violín y no hay forma de que coincida con un selector. En otras palabras '$ ('. Bar'). NextInDocument ('p') == $ ('. Bar'). NextInDocument ('div') == '

rawr!

'. – Jeff

1
(function(jQuery) { 
jQuery.fn.extend({ 
    nextInDocument: function(a) { 
     if (jQuery(this).next(a).length === 0) { 
      //console.log($(this).parent().nextInDocument('p')); 
      jQuery(this).parent().nextInDocument(a); 
     } 
     else 
      return jQuery(this).next(a); 
    } 
}); 
})(jQuery); 
+0

gracias Boopathi. No estoy seguro de si me falta algo. Puse esto en un violín y tu función devolvió el elemento original para cada llamada, por ejemplo '$ ('.bar ') .nextInDocument (' div ') ==

rawr

'. http://jsfiddle.net/jeffrod/nHeGU/ – Jeff

+0

perdón por eso ... lo corrigió ... compruébalo ... tiene otro error menor. ll mejorar ... –

+0

Estoy obteniendo nulos de esto. Todavía no parece funcionar – Jeff

0

toma vistazo a mi código:

HTML

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

<a class="show" href="#">!!!</a> 

JS

$(function() { 
    i = 0; 
    start = 0; 
    $('p').each(function() { 
     if ($(this).hasClass('bar')) { 
      start = i; 
     } 
     i++; 
    }); 
    $('a.show').click(function(){ 
     alert($('p').eq(start+4).text()); 
    }); 
}); 

http://jsfiddle.net/mV8pm/

cambio start+X y obtendrá la etiqueta próxima 'p'

+0

gracias. Esto parece estar muy unido al marcado que di en la demostración, pero necesito algo que pueda funcionar "para cualquier elemento" y agarrar "cualquier elem ent después de él ". no creo que esto sea tan flexible – Jeff

+0

apuesto a que :) lo probará en diferentes DOM. todo lo que necesitas es poner este código en la función JQ. por cierto, la etiqueta del elemento de inicio (seleccionado por clase) y las etiquetas que está buscando después de eso deberían ser las mismas (por ejemplo, 'p'). – bravedick

1

Aquí hay una versión POJS:

function nextInDocument(el, tagName) { 
    var node, nodes = document.getElementsByTagName('*'); 
    var start = false; 
    tagName = tagName.toLowerCase(); 

    for (var i=0, iLen=nodes.length; i<iLen; i++) { 
    node = nodes[i]; 
    if (!start) { 
     if (node == el) start = true; 
    } else { 
     if (node.tagName.toLowerCase() == tagName) { 
     return node; 
     } 
    } 
    } 
} 
+0

buena solución para viejos js. Gracias. jquery puede hacer uso de selectores más complicados, lo que hace que otros fragmentos sean más atractivos para mi situación particular. – Jeff

+0

Tenga cuidado con este enfoque, puede encontrar problemas de rendimiento si hace los selectores demasiado complejos. Considere usar clases en su lugar para que el próximo elemento sea mucho más fácil de encontrar. – RobG

+0

buen punto. consideraré que si el rendimiento se convierte en un problema. – Jeff

Cuestiones relacionadas