2010-08-04 17 views
5

Hola, ¿cómo puedo seleccionar y agregar una clase a la anterior y siguiente etiqueta?jQuery selector

<div class="sub"> 
<ul> 
    <li><a href="#">a</a> 
    <ul> 
    <li><a href="#">b</a> 
     <ul> 
    <li><a href="#">c</a></li> 
    <li><a href="#">d</a></li> 
    <li><a href="#">e</a></li> 
    </ul> 
    </li> 
    <li><a href="#">f</a></li> 
    <li><a href="#">g</a></li> 
    </ul> 
    </li> 
    <li><a href="#">h</a></li> 
    <li><a href="#">i</a></li> 
    <li><a href="#">j</a></li> 
    </ul> 
</div> 

ejemplo: ahora quiero añadir 2 clases CSS (.prev & .Next) a la de los elementos de acuerdo presumen que el ratón está sobre el elemento de <li><a href="#">g</a></li>, por lo que desea añadir el 2 clases a <li><a href="#">f</a></li> y <li><a href="#">h</a></li>

tijeretazo:

$(document).ready(function() { 
    $('li').css({'border-top': '1px solid green','border-bottom': '1px solid green'}); 

    $('li a').each(
     function(intIndex){  
      $(this).mouseover(function(){ 
       $(this).css({'border-top': '1px solid red','border-bottom': '1px solid red'}); 
        $(this).prev().find('li').css({'border-bottom': 'none'}); 
        $(this).next().find('li').css({'border-top': 'none'}); 
       }).mouseout(function(){ 
        $(this).css({'border-top': '1px solid green','border-bottom': '1px solid green'}); 
      }); 
     }  
    ); 
}); 

gracias de antemano

Respuesta

1

Esto debería funcionar. Sin embargo, recorre todo el div .sub, por lo que puede no ser eficiente si esa lista puede ser muy larga.

$(function() { 
    $('.sub li>a').hover(
    function() { 
     var curr = this; 
     var last = ''; 
     var found = false; 
     $('.sub li>a').each(function() { 
     if(found) 
     { 
      $(this).addClass('next'); 
      return false; 
     } 
     if(this == curr) 
     { 
      found = true; 
      $(last).addClass('prev'); 
      $(this).addClass('curr'); //you may want to do this too? 
     } 
     else 
     { 
      last = this; 
     } 
     }); 
    }, 
    function() { 
     $('.sub li>a.next').removeClass('next'); 
     $('.sub li>a.prev').removeClass('prev'); 
    } 
); 
}); 
+0

Thx para respuestas @todos – john

8

Prueba esto: http://jsfiddle.net/rsEaF/1/

var $a = $('.sub li > a'); 

$a.mouseenter(function() { 
    var index = $a.index(this); 
    var prev = (index - 1 >= 0) ? $a.eq(index - 1).addClass('prev') : $(); 
    var next = $a.eq(index + 1).addClass('next'); 
    $a.not(prev).not(next).removeClass('prev next'); 
});​ 

EDIT: Una pequeña corrección. Anteriormente, si pasa el cursor sobre el primer elemento, la clase .prev se agregará al último elemento de la lista. Esto ha sido corregido


EDIT: Aquí hay una versión que utiliza .each() para asignar el manejador. Hacerlo de esta manera es un poco más eficiente porque elimina la necesidad de llamar al $a.index(this); por cada mouseenter.

Pruébelo:http://jsfiddle.net/rsEaF/3/

var $a = $('.sub li > a'); 

$a.each(function(index) { 
    $(this).mouseenter(function() { 
     var prev = (index - 1 >= 0) ? $a.eq(index - 1).addClass('prev') : $(); 
     var next = $a.eq(index + 1).addClass('next'); 
     $a.not(prev).not(next).removeClass('prev next'); 
    }); 
});​ 

EDIT: Si tiene algún problema con la clase correcta de ser eliminado sistemáticamente, deshacerse de esta línea de código:

$a.not(prev).not(next).removeClass('prev next'); 

y en comenzando de el manejador, sustituirlo por:

$a.removeClass('prev next'); 

o:

$a.filter('.prev,.next').removeClass('prev next'); 
3

Usted debe hacer un esfuerzo por tratar de no añadir detectores de eventos como éste

$('li a').each(function (el) { 
    $(el).mouseover(function (e) { 
     /* event handler code */ 
    }); 
}); 

Es suficiente (y más eficiente) para adjuntar un oyente así:

$('li a').mouseover(function (e) { 
    /* event handler code */ 
}); 

También jQuery 1.3 introduce .live() (véase http://api.jquery.com/live/)

$('li a').live('mouseover', function (e) { 
    /* event handler code */ 
}); 

Cualquier evento lanzado por un elemento que coincide con el selector, si existe cuando .live() se llama o se crea después, serán pasados ​​a la función especificada.

+0

-1 "nunca debería adjuntar oyentes de eventos como este". Mal consejo. Cuando no agrega ningún elemento, usar '.live()' no es necesario e introduce una complejidad adicional (por lo tanto, una ejecución más lenta). '.live()' ** es ** una función muy útil, pero no debe * siempre * usarlo. – MvanGeest

+1

Ryan - Con todo respeto, eso no es necesariamente cierto. Aquí hay una versión de mi respuesta que usa '.each()' para asignar el controlador, lo que proporciona un beneficio único. Utiliza la propiedad 'index' de' .each() 'que obvia la necesidad de encontrar el' .index() 'del elemento al pasar sobre la marcha. Véalo aquí: http://jsfiddle.net/rsEaF/3/ – user113716

+0

W Tenney: Veo lo que quiere decir ahora, y tiene más razón: puede omitir '.each()' y simplemente adjuntar a todo elementos al mismo tiempo. Pero patrick dw encontró un uso válido para adjuntar usando '.each()'. Recuperé el -1 después de que editaste tu respuesta. – MvanGeest