2009-05-08 8 views
8

Ecco il mio obiettivo: fare qualcosa su un elemento, un <optgrooup>, se tutti i suoi figli sono invisibili.selezione jquery di elementi senza figli visibili

Il mio codice di sotto delinea in rosso se ha qualsiasi bambini invisibili. Ma voglio farlo solo se tutti i i bambini sono invisibili. Se l'elemento ha bambini visibili, non evidenziarlo.

Come posso modificare il selettore jQuery per farlo?

Grazie in anticipo.

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

Schermata di immagine qui: http://img144.imageshack.us/img144/556/selectexample.gif

+0

Che dire confrontando le lunghezze degli array tra l'invisibile e il totale ldren? –

risposta

0

Avrai bisogno di confrontare una matrice di tutta la: vs visibile: nascosto

qui è una certa pseudo codice

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

Che ne dici di due linee per farlo? Uno per accenderlo per ogni singolo elemento e uno per spegnerlo di nuovo per ognuno con un bambino visibile?

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

Supponendo che si desidera escludere gli elementi senza elementi figlio:

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

Working example.

UPDATE: Questo ha prestazioni molto meglio di quanto la mia risposta originale:

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

+1 Così carino che ho dovuto abbandonare la mia versione piratata di questo inserendo il tuo codice nell'esempio :) – cgp

+0

Ha, grazie! Di solito sono cauto nel mettere troppa logica nei selettori, ma questo era troppo bello per lasciar perdere. –

+0

In realtà, c'è un modo più veloce per farlo con attraversamento anziché selezione: http://stackoverflow.com/questions/841401/jquery-selection-of-elements-with-no-visible-children/841568#841568 –

2

Questo ha un risultato molto migliore rmance del mio original answer:

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

Ti dispiacerebbe spiegare la logica del codice? – Jrgns

1

merito va a Jed Schmidt. Il seguente codice funziona in IE8.

Si noti che IE8 in realtà non nasconde gli elementi <option> nonostante lo stile display: none. Anche IE8 non sembra accettare gli stili border per gli elementi <optgroup>.

campione di lavoro: http://jsbin.com/aquya (modificabile tramite 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

Grazie, è stato grandioso, almeno per evidenziare Sfortunatamente, quello che voglio veramente fare è * nascondere * l'optgroup, non evidenziarlo. Avrei dovuto dirlo nella domanda iniziale - non pensavo che avrebbe fatto la differenza, poiché la mia preoccupazione principale era il selezionatore - ma si scopre che fa la differenza, poiché come hai detto prima, IE ha un bug con occultamento delle opzioni di selezione (e optgroups - vedi http://dev.jquery.com/ticket/1100). Quindi mi sembra di essere sfortunato con IE – Glen

+0

Se non ti dispiace il lavoro extra e le complicazioni, potresti probabilmente contraffarlo eliminando temporaneamente gli elementi che vuoi nascondere (immagino, IE potrebbe non piacermi o). – brianpeiris

1

// risposta alla domanda che cambia css, se lo desideri

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

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

    } else { 

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

    } 

// rimuovere vuoto optgroups esempio

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

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

    } else { 

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

    } 
Problemi correlati