2012-02-22 7 views
14

se provo qualcosa come questo:Come faccio a verificare se 2 selettori jQuery puntano agli stessi elementi?

$(".foo") === $(".foo") // = false 

... ottengo falso. Se invece provo questa query,

$(".foo").get(0) === $(".foo").get(0) // = true 

... Divento vero.

Questo perché:

{a:myObject} !== {a:myObject}; 
[myObject] !== [myObject]; 
myObject  === myObject; 

mi chiedo se non v'è alcun modo succinto per verificare questa uguaglianza, preferibilmente integrato in jQuery. Il secondo metodo che ho scritto funziona correttamente solo se al massimo c'è un elemento che corrisponde a .foo. La soluzione dovrebbe funzionare per qualsiasi quantità di elementi.

Ovviamente non voglio solo controllare ".foo" === ".foo" poiché le selezioni effettive che sto usando sono più complicate. Li ho semplicemente semplificati per questo esempio. (Ad esempio mi può essere utile per controllare che $(this) sta selezionando la stessa cosa di $(".foo").)

+0

Si dovrebbe verificare la risposta di benekastah, ecco una demo che riflette la sua risposta: http://jsfiddle.net/kAv4X/ – MacMac

+0

@lolwut: che non funziona in quanto 'è () 'controlla solo che * almeno uno * degli elementi corrisponda all'altro selettore (cioè è un sottoinsieme). Dai un'occhiata a: http://jsfiddle.net/dYAH3/ (dovrebbe essere falso nel primo avviso, ma è vero). – Senseful

+0

Questa [risposta] (http://stackoverflow.com/a/3856290/989121) sembra la più accurata. – georg

risposta

7

Non c'è nulla nella libreria di base per verificare l'uguaglianza sequenza di oggetti jQuery, ma il seguente dovrebbe fare il trucco:

$.fn.sequenceEqual = function(compareTo) { 
    if (!compareTo || !compareTo.length || this.length !== compareTo.length) { 
    return false; 
    } 
    for (var i = 0, length = this.length; i < length; i++) { 
    if (this[i] !== compareTo[i]) { 
     return false; 
    } 
    } 
    return true; 
} 

che sarebbe utilizzabile in questo modo:

$(".foo").sequenceEqual($(".bar")) 

Per completezza, un contenuto metodo di pari può essere scritto in questo modo:

$.fn.contentsEqual = function(compareTo) { 
    return compareTo && this.length === compareTo.length && this.length === this.filter(compareTo).length; 
} 

Quale sarebbe utilizzabile in questo modo:

$(".foo").contentsEqual($(".bar")) 
-1

Ok, utilizzando solo comandi incorporati jQuery, questo sembra essere quella giusta

$(oneSelector).filter($(anotherSelector)).length == 1 

if ($ (oneSelector) .is ($ (anotherSelector))) ... sono uguali

+6

No. Da [i documenti] (http://api.jquery.com/is/): * "Controlla il set di elementi corrente abbinato a un selettore, elemento o oggetto jQuery e restituisce true se ** almeno uno ** di questi elementi corrisponde agli argomenti indicati. "* (la mia enfasi). –

+1

La tua risposta aggiornata con 'filter' non è ancora corretta, anche se è un grande passo avanti. Dovresti controllare 'length' rispetto alla lunghezza del set originale di elementi corrispondenti, non' 1'. –

+0

@ T.J.Crowder: finché confrontano un singolo elemento (vedere la domanda), va bene. Comunque, filter() è il modo corretto, questo è il modo in cui jQuery implementa() internamente. – georg

4

Se si desidera verificare se entrambi i set contengono esattamente lo stesso eleme nti (possibilmente in un ordine diverso), quindi Array#every in combinazione con $.fn.index potrebbe fare il lavoro:

var $this = $("p"), 
    $other = $("p"); 


// same length and $other contains each element of $this 

var equal = $this.length === $other.length 
       && Array.prototype.every.call($this, function(elem) { 
        return $other.index(elem) > -1; 
       }); 
8

Penso che si sta cercando $().is. Docs here.

var foo, bar; 

foo = $('foo'); 
bar = $('.bar'); 

// This will check to see foo and bar contain the same elements 
foo.is(bar); // true | false 

Edit: @lolwut fornito un jsfiddle per questa risposta. Dopo aver letto i commenti, l'ho aggiornato e ho stabilito che questa risposta non è affidabile per il caso dell'OP.

+1

Questa dovrebbe essere la risposta corretta. – MacMac

+3

@lolwut, nope, 'is()' restituirà 'true' se * almeno uno degli elementi corrisponde agli argomenti specificati *. –

+0

Dai un'occhiata a [T.J. Il commento di Crowder] (http://stackoverflow.com/questions/9400500/how-do-i-check-if-2-jquery-selectors-are-pointing-to-the-same-elements/9401119#comment11878467_9400543) per un spiegazione del perché questo non funziona. – Senseful

3

In alternativa alla risposta di pimvdb (che è molto bella, la sto fornendo solo per completezza), è possibile sfruttare il fatto che add() non aggiungerà elementi già presenti nell'oggetto jQuery.Pertanto, è possibile scrivere:

$.fn.containsSameElements = function(other) { 
    var len = this.length; 
    return other.length == len && this.add(other).length == len; 
};