¿Omitir recursividad en jQuery.find () para un selector?

TL; DR:¿Cómo obtengo una acción como find (), pero bloqueo el recorrido (no punto final, solo omitir) para un cierto selector?

RESPUESTAS$(Any).find(Selector).not( $(Any).find(Mask).find(Selector) )

Hubo muchas respuestas realmente buenas, desearía poder distribuir más los puntos de recompensa, tal vez debería hacer algunas recompensas de 50 puntos en respuesta a algunas de ellas; p ElijoKarl-André Gagnon porque esta respuesta logró hacer que findExclude no sea necesario en una línea, un poco larga. Si bien esto utiliza tres llamadas de búsqueda y un filtro no pesado, en la mayoría de las situaciones, jQuery puede usar una implementación muy rápida que omite el recorrido para la mayoría de los find ().

Las respuestas especialmente buenas se enumeran a continuación:

falsarella: Buena mejora enmi solución, findExclude (), mejor en muchas situaciones

Zbyszek: Una solución basada en filtros similar a la de Falsarella, también buena en eficiencia

Justin: Una solución completamente diferente, pero manejable y funcional para los problemas subyacentes

Cada uno de estos tiene sus propios méritos únicos y merece una mención especial.

Necesito descender completamente a un elemento y comparar los selectores, devolviendo todos los selectores coincidentes como una matriz, pero omito descender al árbol cuando se encuentra otro selector.

Editar: reemplazar el ejemplo de código original con algunos de mi sitio

Esto es para un foro de mensajes que puede tener grupos de mensajes de respuesta anidados dentro de cualquier mensaje.
Sin embargo, tenga en cuenta que no podemos usar el mensaje o las clases de contenido porque el script también se usa para otros componentes fuera del foro. SolamenteInterfaceGroup, Interface ycontrols Las clases son potencialmente útiles, y preferiblemente solo interfaz y controles.

Interactúa con el código y míralo en JS Fiddle, gracias Dave A, aquí Haga clic en los botones mientras ve una consola de JavaScript para ver que la clase de controles está vinculada a un tiempo adicional por nivel de anidamiento de interfaz.

Visual A, Estructura de diseño del foro:

    <li class="InterfaceGroup">
        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
            <li class="InterfaceGroup"> ... condensed ...</li>
        </ul>
        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
        </ul>
        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
            <li class="InterfaceGroup"> ... condensed ...</li>
        </ul>

    </li>

Dentro de cada<li class="InterfaceGroup"> podría haber cualquier número de repeticiones de la misma estructura (cada grupo es un hilo de mensajes) y / o anidamiento más profundo como ...

    <li class="InterfaceGroup">

        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
            <li class="InterfaceGroup">

                <ul class="Interface Message" data-role="MessagePost" >
                    <li class="instance"> ... condensed ... </li>
                    <li class="InterfaceGroup"> ... condensed ...</li>
                </ul>
            </li>
        </ul>
    </li>

Dentro de cada<li class="instance"> ... </li> hay lugares arbitrarios decididos por otro equipo dondeclass="controls" puede aparecer y un oyente de eventos debe estar vinculado. Aunque estos contienen mensajes, otros componentes estructuran su marcado arbitrariamente pero siempre tendrán.controls dentro de.Interface, que se recopilan en un.InterfaceGroupA continuación se incluye una versión de complejidad reducida del contenido interno (para publicaciones en foros) como referencia.

Visual B, Contenido del mensaje con clase de controles:

<ul class="Interface Message" data-role="MessagePost" >
    <li class="instance">
      <ul class="profile"> ...condensed, nothing clickable...</ul>
      <ul class="contents">
        <li class="heading"><h3>Hi there!</h3></li>
        <li class="body"><article>TEST Message here</article></li>
        <li class="vote controls">
          <button class="up" data-role="VoteUp" ><i class="fa fa-caret-up"> </i><br/>1</button>
          <button class="down" data-role="VoteDown" >0<br/><i class="fa fa-caret-down"> </i></button>
        </li>
        <li class="social controls">
          <button class="reply-btn" data-role="ReplyButton" >Reply</button>
        </li>
      </ul>
    </li>
    <li class="InterfaceGroup" >    <!-- NESTING OCCURRED -->
      <ul class="Interface Message" data-role="MessagePost" >
          <li class="instance">... condensed ... </li>
          <li class="InterfaceGroup" >... condensed ... </li>
      </ul>
   </li>
</ul>

Solo podemos unirnos a controles que sondentro de una clase de interfaz, instance puede existir o no, pero la interfaz existirá.Los eventos burbujean a.controls elementos y tener una referencia a la.Interface que los sostiene..

Entonces estoy tratando de$('.Interface').each( bind to any .controls not inside a deeper .Interface )

Esa es la parte difícil, porque

.Interface .controls seleccionará lo mismo.control varias veces en .each ().not ('. Interface .Interface .controls') cancela los controles en cualquier anidamiento más profundo

¿Cómo puedo hacer esto usando jQuery.find () o un método jQuery similar para esto?

He estado considerando que, quizás, usar niños con un selector nopodría trabaja ypodría estar haciendo lo mismo que encontrar debajo del capó, pero no estoy tan seguro de que realmente sea o no cause un rendimiento horrible. Aún así, una respuesta recurrente .children efectivamente es aceptable.

ACTUALIZACIÓN: Originalmente intenté usar un ejemplo de psuedo por brevedad, pero espero que ver una estructura de foro ayude a aclarar el problema ya que son estructuras anidadas naturalmente. A continuación, también publico JavaScript parcial como referencia, la línea dos de la función init es la más importante.

JavaScript reducido parcial:

var Interface=function()
{
    $elf=this;

    $elf.call=
    {
        init:function(Markup)
        {
            $elf.Interface = Markup;
            $elf.Controls = $(Markup).find('.controls').not('.Interface .controls');
            $elf.Controls.on('click mouseenter mouseleave', function(event){ $elf.call.events(event); });
            return $elf;
        },
        events:function(e)
        {
            var classlist = e.target.className.split(/\s+/), c=0, L=0;
            var role = $(e.target).data('role');

            if(e.type == 'click')
            {
                CurrentControl=$(e.target).closest('[data-role]')[0];
                role = $(CurrentControl).data('role');

                switch(role)
                {
                    case 'ReplyButton':console.log('Reply clicked'); break;
                    case 'VoteUp':console.log('Up vote clicked'); break;
                    case 'VoteDown':console.log('Down vote clicked'); break;
                    default: break;
                }
            }
        }
    }
};

$(document).ready( function()
{
    $('.Interface').each(function(instance, Markup)
    {
        Markup.Interface=new Interface().call.init(Markup);
    });
} );

Respuestas a la pregunta(8)

Su respuesta a la pregunta