Modo più sicuro per selezionare tutti i pulsanti di opzione senza un attributo valore

http://jsfiddle.net/CuURK/

Ho un numero di pulsanti radio come:

 

Devo selezionare tutti i pulsanti di opzione senza un attributo value nel markup e quindi impostare l’attributo per questi. I seguenti test non funzionano:

 $('#myradio').val() // returns 'on' $('#myradio').attr('value') // returns 'on' 

Questo sembra funziona in Chrome, ma non in IE8:

 $('#myradio').is('[value]'); //doesn't work in IE8 

Qual è il modo più sicuro per determinare se un elemento ha un attributo valore? C’è una spiegazione per il comportamento sopra?

Il modo migliore e più veloce è quello di attenersi ai selettori CSS:

 $('input[type="radio"]:not([value])') 

restituirà tutti gli elementi di input che sono radio senza il value dell’attributo presente – Vedi questo violino .

Dal momento che restituisce una collezione puoi fare tutto ciò che vuoi, come aggiungere l’attributo mancante, aggiungere una class, hide o rimuovere gli elementi, senza la necessità di un ciclo .each() , perché la maggior parte dei metodi di jQuery può funzionare su raccolte – Vedi questo violino .

Quindi nel tuo caso per aggiungere l’attributo mancante:

 $('input[type="radio"]:not([value])').attr('value', 'foobar'); 

Ricorda che il selettore è un selettore CSS3 valido.


Aggiornare:

In base a ciò, il nostro selettore non corrisponderà mai a IE8, poiché IE8 non può corrispondere usando [attr] se l’attr assegnato è vuoto (e stiamo cercando di farlo corrispondere).

Quindi dobbiamo eseguire il looping degli input s e controllare se il value dell’attributo è uguale a '' , poiché se manca jQuery restituisce una stringa vuota.

Ecco un violino , che funziona su IE8 (sono riuscito a provarlo su un IE8 reale).

 $('input[type="radio"]').each(function (index, element) { var $this = $(this); if ($this.get(0).outerHTML.indexOf('value') === -1) { $this.addClass('found'); } }); 

Per ogni elemento controlliamo se la sua proprietà outerHTML contiene la stringa del value . Se non contiene la stringa, l’abbiamo trovata. Come vedrai, fallisce solo con un nodo come questo:

  

perché IE lo analizza come:

  

Non è la soluzione efficiente, ma funziona.

A proposito, come ho detto nei commenti, è necessario un input con type="radio" per avere l’attributo value . In caso contrario, il documento non è valido e il browser potrebbe tentare di correggere la struttura del documento – Firefox sembra aggiungere un valore predefinito di on , mentre Safari non lo fa.

Infine, jQuery’s .attr() restituisce undefined se l’attributo cercato non esiste ( vedi la fonte ): quindi in genere è ansible verificare

 typeof $('#foo').attr('attributeName') === 'undefined' 

per vedere se l’elemento ha l’ attributeName attributeName.

Quanto segue funzionerà:

 $('input[type="radio"]:not([value])') 

Come mostrato qui: http://jsfiddle.net/4sLzc/1/

La ragione per cui .val() restituisce “on” è perché è un comportamento predefinito per un pulsante di opzione senza un attributo valore che ritorna “on”. Questa non è una cosa jQuery: la stessa cosa accade con un semplice JavaScript se si dice valore document.getElementById("myradio").value O quando il modulo viene inviato, si trova sul lato server che “on” è il valore inviato reale .

Questo corrisponderebbe per gli elementi che hanno un attributo valore

 $('input[value]'); 

e questo per quelli che non lo fanno

 $('!input[value]');