2012-04-15 16 views
15

Sto lavorando per creare un modo più semantico di controllo degli elementi con jQuery. Utilizzando $("#element").length > 0 solo in realtà non mi sento molto bene formulate per me, così io sto facendo la mia aggiunta di selezione per l'utilizzo in .is:Restituisce "True" su jQuery Selector Array vuoto?

if($("#element").is(":present")) { 
    console.log("It's aliiiveeee!!"); 
} 

Quella parte è stato facile, come questo:

$.extend($.expr[':'],{ 
    present: function(a) { 
     return $(a).length > 0; 
    } 
}); 

voglio fare un passo ulteriore, e rendere più facile per vedere se un elemento non esiste, utilizzando la sintassi simile:

$.extend($.expr[':'],{ 
    present: function(a) { 
     return $(a).length > 0; 
    }, 
    absent: function(a) { 
     return $(a).length === 0; 
    } 
}); 

$(function() { 
    if($("#element").is(":absent")) { 
    console.log("He's dead, Jim."); 
    } 
}); 

Ma questa parte è sorprendentemente difficile da fare. Penso che sia perché sto abbattendo gli elementi restituiti per ottenere un risultato, e il paring del selettore su .length === 0 è lo stesso che non richiedere nessun elemento: restituisce false indipendentemente da cosa.

Ho provato un sacco di modi diversi per invertire le cose e ottenere questo per tornare vero quando l'elemento non esiste, e falso se lo fa:

return $(a).length === 0; 

return !($(a).length > 0); 

if(!($(a).length > 0)) { 
    return true; 
} 

if($(a).length > 0) { 
    return false; 
} else { 
    return true; 
} 

return !!($(a).length === 0); 

// etc... 

C'è un modo semplice per ottenere questo per restituire solo true se l'elemento non esiste e false se lo fa?

risposta

14

La definizione di is:

Controllare la corrente unico set di elementi su un selettore, elemento, o oggetto jQuery e restituisce vero se almeno uno di questi elementi corrisponde gli argomenti dati.

Il problema è che poiché non ci sono elementi, non è possibile che uno dei tuoi elementi corrisponda ad alcune condizioni. jQuery non chiama nemmeno il tuo codice perché non ci sono elementi.

MODIFICA: per chiarire leggermente, il codice viene chiamato una volta per ogni elemento nell'oggetto (almeno finché non si restituisce true). Nessun elemento significa che il codice non viene mai chiamato. a nel tuo codice è sempre un singolo elemento.

EDIT2: Con questo in mente, questa sarebbe un'implementazione più efficiente delle present:

$.extend($.expr[':'],{ 
    present: function(a) { 
     return true; 
    } 
}); 
+0

Quindi, '.is' non è progettato per restituire true quando non ci sono elementi nel set di selettori abbinati? Un'altra opzione che avevo preso in considerazione era l'utilizzo di: 'if ($ (" #elemento "). È (": not (: present) ")) { console.log (" È morto, Jim. "); } Ma stranamente, anche questo non funziona. –

+1

@Code Junkie: Ancora una volta, non hai alcun elemento per usare '.is()', in modo tale che semplicemente la funzione non venga chiamata. Non importa quale selettore ci passi, niente succederà! – BoltClock

+0

Quindi potrebbe non esserci modo di restituire true su un risultato di selettore vuoto? –

1

0 è "falsy" in JavaScript.

È possibile restituire !$(a).length.

+4

Mentre questo è vero, si può mettere tutto quello che vuoi lì, il codice non verrà mai eseguito se non ci sono elementi. –

0

ne dite:

if (!$(a)[0]) { 
    // $(a) is empty 
} 

Quindi, $(a)[0] recupera il primo elemento nell'oggetto jQuery. Se quell'elemento è nullo/non definito, significa che l'oggetto jQuery è vuoto.

5

si può semplicemente utilizzare

if(​$('element').length) // 1 or 0 will be returned 

o

$.extend($.expr[':'],{ 
    present: function(a) { 
     return $(a).length; 
    } 
}); 

if($('#element').is(':present')) 
{ 
    // code for existence 
} 
else 
{ 
    // code for non-existence 
} 

Example .

2

Dato che $().is() non verrà eseguito anche quando la raccolta è vuota, il selettore :present è piuttosto superfluo. Quindi, piuttosto che giocare con $.expr[':'], mi piacerebbe andare con estensione $.fn per contenere funzione appropriata, ad esempio:

$.fn.extend({ 
    hasAny: function() { 
     return this.length > 0; 
    }, 
}); 

o

$.fn.extend({ 
    isEmpty: function() { 
     return this.length == 0; 
    }, 
}); 

La ragione per cui ho personalmente andare con questo approccio è che i selettori sono in genere utilizzato per controllare particolari proprietà degli elementi (confrontare , :selected, :selected, :hover, ecc.), non le proprietà dell'insieme di elementi jQuery nel suo complesso (ad esempio .size(), .index()).

Uso sarebbe naturalmente simile al seguente:

if ($('#element').isEmpty()) 
    console.log("He's dead, Jim."); 
+0

Sì, probabilmente è in definitiva un modo migliore. Stavo principalmente giocando con tutte le opzioni, per vedere quale sarebbe stato il modo migliore. Suonerò con questo prossimo. ^^ –

Problemi correlati