2009-05-08 22 views
8

Aquí está mi objetivo: hacer algo sobre un elemento, un <optgrooup>, si todos sus hijos son invisibles.selección jQuery de elementos que no tienen hijos visibles

Mi código a continuación describe el en rojo si tiene cualquier niños invisibles. Pero quiero hacerlo solo si todos los niños son invisibles. Si el elemento tiene hijos que están visibles, no lo resalte.

¿Cómo puedo ajustar el selector de jQuery para hacer eso?

Gracias de antemano.

<select multiple="multiple" name="availableInstanceId" id="availableInstanceId"> 
<optgroup label="Option Group 1"> 
    <option >visible item 1</option> 
    <option >visible item 2</option> 
</optgroup> 
<optgroup label="Option Group 2 - Should be highlighted"> 
    <option style="display:none;">invisible A</option> 
    <option style="display: none">invisible B</option> 
</optgroup> 

<optgroup label="Option Group 3 - Should not be highlighted"> 
    <option >visible C</option> 
    <option style="display: none">invisible D</option> 
</optgroup></select> 

<script type="text/javascript"> 
var filterOptions = function(e) { 
    // Goal: highlight the <optgroup>'s that have *only* invisible children 
    $('#availableInstanceId > * > *:hidden').parent().css("border","3px solid red"); 
} 
$(document).ready(function() { 
    filterOptions(); 
}); 
</script> 

Captura de pantalla de la imagen aquí: http://img144.imageshack.us/img144/556/selectexample.gif

+0

¿Qué hay de comparando las longitudes de las matrices entre el chi invisible y el total ldren? –

Respuesta

0

Tendrá que comparar una matriz de todos los: vs visibles: oculto

Aquí hay un código de pseudo

if ($("#element:hidden").length == $("#element:visible").length) { 
    // Do stuff 
} ... 
1

¿Qué tal dos líneas para hacerlo? Uno para encenderlo para cada elemento y otro para apagarlo nuevamente para cada uno con un niño visible.

$('#availableInstanceId > *').css("border","3px solid red"); 
$('#availableInstanceId > * > *:visible').parent().css("border","none"); 
12

Suponiendo que desea excluir elementos con los elementos secundarios:

$(":has(*):not(:has(:visible))") 

Working example.

ACTUALIZACIÓN: Esto tiene un rendimiento mucho mejor que mi respuesta original:

$(":hidden").parent().not($(":visible").parent()) 
+1

+1 Tan lindo que tuve que abandonar mi propia interpretación pirateada de esto y poner en tu código el ejemplo :) – cgp

+0

¡Gracias! Normalmente soy cauteloso de poner tanta lógica en los selectores, pero este era demasiado bueno como para dejarlo pasar. –

+0

En realidad, hay una manera más rápida de hacer esto con el recorrido en lugar de la selección: http://stackoverflow.com/questions/841401/jquery-selection-of-elements-with-no-visible-children/841568#841568 –

2

Esto tiene mucho mejor perfo rmance que mi original answer:

$(":hidden").parent().not($(":visible").parent()) 
+0

¿Te importaría explicar la lógica del código? – Jrgns

1

crédito va a Jed Schmidt. El siguiente código funciona en IE8.

Tenga en cuenta que IE8 en realidad no oculta los elementos <option> a pesar del estilo display: none. Además, IE8 no parece aceptar los estilos border para los elementos <optgroup>.

muestra de trabajo: http://jsbin.com/aquya (editable a través de http://jsbin.com/aquya/edit)

$(document).ready(function() { 
    // Prevent CSS inherits 
    $("option").css('backgroundColor', 'white') 

    $("option") 
    .filter(function(){ 
     return this.style.display == 'none'; 
    }) 
    .parent() 
    .not($('option').filter(function(){ 
     return this.style.display != 'none'; 
    }).parent()) 
    .css('backgroundColor', 'blue') 
    .css('border', '1px solid red'); //this doesn't work in IE8 
}); 
+0

Gracias, esto fue genial, al menos para resaltar Desafortunadamente, lo que realmente quiero hacer es * ocultar * el grupo de opciones, no resaltarlo. Debería haber dicho eso en la pregunta original, no pensé que marcaría la diferencia, ya que mi principal preocupación era el selector, pero resulta que sí hace la diferencia, ya que como mencionaste antes, IE tiene una error al ocultar las opciones de selección (y grupos de opciones - ver http://dev.jquery.com/ticket/1100). Así que parece que no tengo suerte con IE – Glen

+0

. Si no te molesta el trabajo extra y la complicación, probablemente puedas fingir borrando temporalmente los elementos que deseas ocultar (supongo que a IE no le gustaría eso ya sea). – brianpeiris

1

// respuesta a la pregunta cambiar css según se desee

if($.browser.msie || $.browser.safari){ 

     $('optgroup:not(:has(:hidden))').css("border","3px solid red"); 

    } else { 

     $('optgroup:not(:has(:visible))').css("border","3px solid red"); 

    } 

// eliminar optgroups ejemplo vacío

if($.browser.msie || $.browser.safari){ 

     $('optgroup:not(:has(:hidden))').remove(); 

    } else { 

     $('optgroup:not(:has(:visible))').remove(); 

    } 
Cuestiones relacionadas