Come posso rilevare se un selettore restituisce null?


271

Qual è il modo migliore per rilevare se un selettore jQuery restituisce un oggetto vuoto. Se fate:

alert($('#notAnElement'));

ottieni [oggetto oggetto], quindi il modo in cui lo faccio ora è:

alert($('#notAnElement').get(0));

che scriverà "indefinito", e quindi puoi fare un controllo per quello. Ma sembra molto male. Quale altro modo c'è?

Risposte:


494

Il mio preferito è estendere jQuery con questa piccola comodità:

$.fn.exists = function () {
    return this.length !== 0;
}

Usato come:

$("#notAnElement").exists();

Più esplicito rispetto all'utilizzo della lunghezza.


2
Perché hai racchiuso 'this' in $ ()? "questo" in questo contesto non indicherebbe effettivamente l'oggetto jQuery?
Adham Atta,

1
Trovo che tornare thissia molto più utile di true. Vedi la mia risposta porting presencemetodo di Rails .
Marc-André Lafortune,

5
Se si desidera mantenere la capacità di concatenarsi, nel caso in cui la funzione ritorni vera, o se si desidera utilizzare questo metodo per assegnare thisa una variabile, si consiglia di modificare l'istruzione return in ciò che CSharp ha.
Hanna,

1
Magnar, puoi spiegarmi come funziona questa funzione di "estensione"? Suppongo che sia un concetto Javascript e non un concetto strettamente JQuery. Ho esaminato la prototipazione ma non sono sicuro che si applichi qui e perché la sintassi sarebbe "$ .fn".
KyleM,

3
@Adam Sì. Ma in tal caso, dovresti semplicemente rilasciare il controllo esistenze, dato come funziona jQuery. Non farà qualcosa se non ci sono elementi corrispondenti al selettore.
Magnar

197
if ( $("#anid").length ) {
  alert("element(s) found")
} 
else {
  alert("nothing found")
}

67

Il selettore restituisce una matrice di oggetti jQuery. Se non viene trovato alcun elemento corrispondente, restituisce un array vuoto. È possibile controllare la .lengthraccolta restituita dal selettore o verificare se il primo elemento dell'array è "non definito".

È possibile utilizzare uno qualsiasi dei seguenti esempi all'interno di un'istruzione IF e tutti producono lo stesso risultato. Vero, se il selettore ha trovato un elemento corrispondente, falso altrimenti.

$('#notAnElement').length > 0
$('#notAnElement').get(0) !== undefined
$('#notAnElement')[0] !== undefined

1
Uso a .lengthmeno che il codice non sia caldo. È certamente il più chiaro con l'intento. Inoltre, .size()è deprecato ed è stato per anni (dal 1.8). Ho intenzione di modificare la tua risposta e rimuoverla, sentiti libero di aggiungerla di nuovo con una nota, ma è così vecchia, penso che sia meglio andare.
Evan Carroll,

1
Tecnicamente restituisce un oggetto jQuery che non contiene nodi DOM. Dire che restituisce un array vuoto non è giusto.
Vigrant,

39

Mi piace fare qualcosa del genere:

$.fn.exists = function(){
    return this.length > 0 ? this : false;
}

Quindi puoi fare qualcosa del genere:

var firstExistingElement = 
    $('#iDontExist').exists() ||      //<-returns false;
    $('#iExist').exists() ||          //<-gets assigned to the variable 
    $('#iExistAsWell').exists();      //<-never runs

firstExistingElement.doSomething();   //<-executes on #iExist

http://jsfiddle.net/vhbSG/


6
@Ehsan In realtà non è un duplicato della risposta accettata ... nota che la risposta accettata restituisce solo vero / falso mentre questa risposta restituisce l'oggetto originale ("questo") o falso. Questa risposta ti consente di fare cose aggiuntive con il valore di ritorno (come il concatenamento di funzioni aggiuntive) se non è falso.
RSW,

1
Ho esattamente lo stesso codice nel mio toolkit standard. Questo modulo è equivalente a object.presence in Rails ed è utilissimo nel costrutto fallthrough descritto da @CSharp.
inopinatus,

Questa è una buona risposta, ma sarebbe utile se spiegassi cosa succede se NON esiste NESSUNO degli elementi testati. Risposta breve: TypeError: firstExistingElement.doSomething is not a function. Puoi racchiudere l'intera variabile assegnazione / test in un if () e fare qualcosa solo se viene trovato un elemento ....
Stephen R,

9

Mi piace usare presence, ispirato a Ruby on Rails :

$.fn.presence = function () {
    return this.length !== 0 && this;
}

Il tuo esempio diventa:

alert($('#notAnElement').presence() || "No object found");

Lo trovo superiore a quello proposto $.fn.existsperché è ancora possibile utilizzare operatori booleani o if, ma il risultato è più utile. Un altro esempio:

$ul = $elem.find('ul').presence() || $('<ul class="foo">').appendTo($elem)
$ul.append('...')

7

Le mie preferenze e non ho idea del perché questo non sia già in jQuery:

$.fn.orElse = function(elseFunction) {
  if (!this.length) {
    elseFunction();
  }
};

Usato così:

$('#notAnElement').each(function () {
  alert("Wrong, it is an element")
}).orElse(function() {
  alert("Yup, it's not an element")
});

Oppure, come appare in CoffeeScript:

$('#notAnElement').each ->
  alert "Wrong, it is an element"; return
.orElse ->
  alert "Yup, it's not an element"


0

Si consiglia di farlo sempre per impostazione predefinita. Ho faticato a racchiudere la funzione jquery o il metodo jquery.fn.init per farlo senza errori, ma puoi fare una semplice modifica alla fonte jquery per farlo. Sono incluse alcune linee circostanti che puoi cercare. Consiglio di cercare la fonte jquery perThe jQuery object is actually just the init constructor 'enhanced'

var
  version = "3.3.1",

  // Define a local copy of jQuery
  jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    var result = new jQuery.fn.init( selector, context );
    if ( result.length === 0 ) {
      if (window.console && console.warn && context !== 'failsafe') {
        if (selector != null) {
          console.warn(
            new Error('$(\''+selector+'\') selected nothing. Do $(sel, "failsafe") to silence warning. Context:'+context)
          );
        }
      }
    }
    return result;
  },

  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

jQuery.fn = jQuery.prototype = {

Ultimo ma non meno importante, puoi ottenere il codice sorgente jquery non compresso qui: http://code.jquery.com/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.