2014-09-30 18 views
36

Perché il cast di data-value="2.0" è convertito in una stringa e il valore di data-value="2.5" viene convertito in numero? Posso gestire questa multa nella mia funzione. Sto solo cercando di capire un po 'di più su come Javascript gestisce numeri e stringhe. Questo mi ha colto alla sprovvista.HTML5 data- * tipo di attributo stringhe e numeri di fusione

<a data-value="2.0">2.0</a> 
<a data-value="2.5">2.5</a> 
$("a").click(function() { 
    alert(typeof $(this).data("value")); 
}); 

[ Fiddle With It ]

+0

Non so perché questo sta accadendo, ma si può vedere che galleggia che termina con un '0' sono sempre fatto finta di essere archi. Forse perché l'ultimo '0' è irrilevante e quindi interpretato come testo. Ad esempio: '2.5' è numero e' 2.50' è una stringa. – TheFrozenOne

+13

Il metodo '.data' di jQuery proverà a convertire qualunque cosa si trovi nell'attributo' data- * '- se lo si vuole come valore stringa grezzo, usare' .attr ("data - *") ' – tymeJV

+0

@tymeJV grazie per il dritta! – Matt

risposta

28

Questi valori sono semplicemente stringhe di vaniglia javascript; non sta tentando alcuna conversione da solo.

[...document.querySelectorAll("a")].forEach(a => 
 
    console.log("type: %s, value: %o", 
 
       typeof a.dataset.value, 
 
       a.dataset.value) 
 
);
<a data-value="2.0">2.0</a> 
 
<a data-value="2.5">2.5</a>

jQuery, invece, cerca di determinare e convertire il tipo appropriato quando si accede agli attributi tramite data(). È (discutibilmente) un problema con la loro implementazione. La loro documentation (sottolineatura mia) in realtà affronta questo:

Ogni tentativo è fatto per convertire la stringa in un valore JavaScript (questo include booleani, numeri, oggetti, array e null). Un valore viene convertito in un numero solo se così facendo non cambia la rappresentazione del valore. Ad esempio, "1E02" e "100.000" sono equivalenti come numeri (valore numerico 100) ma la loro conversione altererebbe la loro rappresentazione in modo da essere lasciati come stringhe. Il valore stringa "100" è convertito al numero 100.

Vedi anche HTMLElement. dataset

+1

Grazie! Non avevo realizzato che JQuery l'avesse fatto. Ho passato ore a combinare uno script di 600 righe cercando un bug e ora mi sento molto sciocco! +1 per l'esempio. – Matt

+1

Buono a sapersi su questo cambiamento. È venuto fuori così da 1.8 rc 1. – zzzzBov

1

Sembra essere trattare tale estensione" .0" del numero come una stringa.

Se tutti i valori dei dati stanno per essere in arrivo in quel formato, solo frustare un parseFloat() su quelle ventose come questo:

$("a").click(function() { 
    alert(typeof parseFloat($(this).data("value"))); 
}); 

In questo modo non importa se sono stringhe o numeri , saranno sempre trattati come numeri (decimali intatti).

+2

Non sarebbe appropriato ['parseFloat()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat) dato il '2.5'? – canon

+0

@canon è assolutamente corretto –

1

Come menzionato da tymeJV, questo sembra un problema con il modo in cui jquery gestisce l'autoconversione. Se si usa "2", si dà anche un numero, quindi suppongo che sia solo un caso strano in cui gestiscono le cose. Incoraggerei semplicemente usando .attr ('xxx') e analizzando i tuoi dati al suo tipo noto.

0

Penso che sia più una domanda su come jquery identifica i numeri. Se usi alert(typeof(this.getAttribute("data-value")));, sputa che è una stringa entrambe le volte (che è previsto). Per quanto ne so, tutto in un attributo html è considerato una stringa, solo librerie diverse possono avere un comportamento predefinito che le interpreta in modo diverso.

Inoltre, un modo veloce per ottenere un numero sarebbe qualcosa sulla falsariga di ...

var someNumber = +$(someElt).data("value"); 

il + causerà tipo di coercizione, se il valore restituito è una stringa, o lasciarlo solo se si tratta di già un numero.

4

Per impostazione predefinita, qualsiasi cosa analizzata da un attributo sarà una stringa, sarà necessario convertirla in un numero se è necessario utilizzarlo come numero. Il modo migliore sono stato in grado di gestire questo è avvolgendolo con la funzione Number (javascript nativo)

var number = Number($(this).data("value")); 
parseInt restituirà un intero (numero intero), quindi se si desidera mantenere i valori decimali dovrai usare Number. Parola di cautela con parseInt, è sempre meglio specificare la base se si desidera analizzare un int, parseInt ($ (questo) .data ("valore"), 10);
+0

Perché vorrebbe 'parseInt()' a tutti? Ha valori decimali come '2.5'. – canon

+0

Ho postato la mia risposta dopo @dave lunny, che aveva fatto riferimento a parseInt in precedenza ma da allora lo ha modificato. Avrei dovuto essere più esplicito Colpirò quella parte per evitare confusione. – zmehboob

Problemi correlati