.prop () vs .attr ()


2301

Quindi jQuery 1.6 ha la nuova funzione prop().

$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})

o in questo caso fanno la stessa cosa?

E se io non devo passare ad usare prop(), tutte le vecchie attr()chiamate si romperà se posso passare a 1,6?

AGGIORNARE

selector = '#id'

$(selector).click(function() {
    //instead of:
    var getAtt = this.getAttribute('style');
    //do i use:
    var thisProp = $(this).prop('style');
    //or:
    var thisAttr = $(this).attr('style');

    console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>

(vedi anche questo violino: http://jsfiddle.net/maniator/JpUF2/ )

La console registra getAttributecome una stringa e attrcome una stringa, ma propcome a CSSStyleDeclaration, Perché? E in che modo ciò influirà sulla mia programmazione in futuro?


17
Questo sarà di sicuro interesse: books.google.ca/…

28
@Neal, è perché questa modifica trascende jQuery. La differenza tra gli attributi HTML e le proprietà DOM è enorme.

7
Mi rende triste vedere che jQuery ha annullato le modifiche. Stanno andando nella direzione sbagliata.

4
@Neal. Sì, e questo complica ulteriormente il problema invece di separare i due metodi.

6
@BritishDeveloper la risposta è più complicata del semplice affermare di usare sempre x o y perché dipende da ciò che si intende ottenere. Vuoi l'attributo o vuoi la proprietà? sono due cose molto diverse.
Kevin B,

Risposte:


1876

Aggiornamento 1 novembre 2012

La mia risposta originale si applica specificamente a jQuery 1.6. Il mio consiglio rimane lo stesso ma jQuery 1.6.1 ha cambiato leggermente le cose: di fronte al mucchio previsto di siti Web rotti, il team di jQuery è tornato attr()a qualcosa di simile (ma non esattamente lo stesso) al suo vecchio comportamento per gli attributi booleani . Anche John Resig ne ha scritto un blog . Vedo la difficoltà in cui si trovavano ma non sono ancora d'accordo con la sua raccomandazione di preferire attr().

Risposta originale

Se hai sempre usato jQuery e non direttamente il DOM, questo potrebbe essere un cambiamento confuso, sebbene sia sicuramente un miglioramento concettualmente. Non così buono per i bazillions di siti che utilizzano jQuery che si romperà a seguito di questo cambiamento.

Riassumo i principali problemi:

  • Di solito vuoi prop()piuttosto che attr().
  • Nella maggior parte dei casi, prop()fa quello che era attr()solito fare. Sostituire le chiamate con attr()con prop()nel tuo codice generalmente funzionerà.
  • Le proprietà sono generalmente più semplici da gestire rispetto agli attributi. Un valore di attributo può essere solo una stringa mentre una proprietà può essere di qualsiasi tipo. Ad esempio, la checkedproprietà è un valore booleano, la styleproprietà è un oggetto con proprietà individuali per ogni stile, la sizeproprietà è un numero.
  • Laddove esistono sia una proprietà che un attributo con lo stesso nome, in genere l'aggiornamento di uno aggiornerà l'altro, ma non è così per alcuni attributi di input, come valuee checked: per questi attributi, la proprietà rappresenta sempre lo stato corrente mentre L'attributo (eccetto nelle vecchie versioni di IE) corrisponde al valore / controllo predefinito dell'input (riflesso nella proprietà defaultValue/ defaultChecked).
  • Questa modifica rimuove parte del livello di jQuery magico bloccato davanti ad attributi e proprietà, il che significa che gli sviluppatori di jQuery dovranno imparare un po 'sulla differenza tra proprietà e attributi. Questa è una buona cosa.

Se sei uno sviluppatore jQuery e sei confuso da tutta questa attività su proprietà e attributi, devi fare un passo indietro e imparare un po 'su di esso, dal momento che jQuery non sta più cercando di proteggerti da queste cose. Per la parola autorevole ma un po 'secca sull'argomento, ci sono le specifiche: DOM4 , DOM HTML , DOM Livello 2 , DOM Livello 3 . La documentazione DOM di Mozilla è valida per la maggior parte dei browser moderni ed è più facile da leggere rispetto alle specifiche, quindi potresti trovare utile il loro riferimento DOM . C'è una sezione sulle proprietà degli elementi .

Come esempio di come le proprietà sono più semplici da gestire rispetto agli attributi, prendere in considerazione una casella di controllo inizialmente selezionata. Ecco due possibili pezzi di HTML valido per fare questo:

<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">

Quindi, come fai a sapere se la casella di controllo è selezionata con jQuery? Guarda Stack Overflow e troverai comunemente i seguenti suggerimenti:

  • if ( $("#cb").attr("checked") === true ) {...}
  • if ( $("#cb").attr("checked") == "checked" ) {...}
  • if ( $("#cb").is(":checked") ) {...}

Questa è in realtà la cosa più semplice al mondo a che fare con la checkedproprietà booleana, che esiste e ha funzionato in modo impeccabile in tutti i principali browser con script dal 1995:

if (document.getElementById("cb").checked) {...}

La proprietà rende inoltre banale la selezione o deselezione della casella di controllo:

document.getElementById("cb").checked = false

In jQuery 1.6, questo diventa inequivocabilmente

$("#cb").prop("checked", false)

L'idea di utilizzare l' checkedattributo per lo scripting di una casella di controllo è inutile e non necessaria. La proprietà è ciò di cui hai bisogno.

  • Non è ovvio quale sia il modo corretto di selezionare o deselezionare la casella di controllo utilizzando l' checkedattributo
  • Il valore dell'attributo riflette lo stato predefinito anziché l'attuale stato visibile (tranne in alcune versioni precedenti di IE, rendendo le cose ancora più difficili). L'attributo non dice nulla sul fatto che la casella di controllo nella pagina sia selezionata. Vedi http://jsfiddle.net/VktA6/49/ .

2
@TJCrowder, allora quali?
Naftali aka Neal

9
@Neal: Se vuoi sapere quali elementi proprietà DOM hanno e come attributi possono seminare i loro valori, mantenere tali link mano: La DOM2 specifiche HTML , il DOM2 spec, e DOM3 spec. Gli indici in ogni caso sono eccellenti e ti collegano direttamente a una descrizione completa della proprietà, da dove proviene il suo valore, ecc.
TJ Crowder

4
@Neal: Re ciò che lo rende diverso: la fonte e la natura delle informazioni. Guarda l' valueesempio di Tim , per esempio. Una funzione chiamata attrche recupera la proprietà value anziché l'attributo "valore" non ha molto senso (e possono essere diversi). Andare avanti, attrfare attributi e propfare proprietà sarà più chiaro, anche se per alcuni la transizione sarà dolorosa. Non prenderla nel modo sbagliato, non c'è niente come tornare indietro e leggere le specifiche per avere un'idea delle proprietà.
TJ Crowder,

54
@Neal: un elemento DOM è un oggetto. Le proprietà sono proprietà di quell'oggetto, proprio come qualsiasi altro oggetto di programmazione. Alcuni di questi oggetti di scena ottengono i loro valori iniziali dagli attributi nel markup, che sono anche memorizzati sull'oggetto DOM in una mappa separata degli attributi. Nella maggior parte dei casi, scrivere su un puntello cambia solo il prop, anche se purtroppo ci sono alcuni puntelli che scrivono eventuali cambiamenti attraverso l'attr sottostante ( valueper esempio), ma proviamo principalmente a ignorarlo. Il 99% delle volte, vuoi lavorare con oggetti di scena. Se devi lavorare con un attributo reale, probabilmente lo saprai.
TJ Crowder,

4
@Tim: "Cambiare la valueproprietà di un input non cambia il suo valueattributo nei browser moderni" Non pensavo che lo facesse, motivo per cui ho iniziato a usarlo come esempio, ma quando ho iniziato a codificare l'esempio, maledetto se non è stato aggiornato su Chrome, Firefox, Opera, IE ... - jsbin.com/ahire4 Si scopre che è perché stavo usando un input[type="button"]per il mio esperimento. Esso non aggiorna l'attributo su un input[type="text"]- jsbin.com/ahire4/2 Parlare di contorto !! Non solo l'elemento, ma il tipo di esso ...
TJ Crowder,

664

Penso che Tim l'abbia detto abbastanza bene , ma facciamo un passo indietro:

Un elemento DOM è un oggetto, una cosa in memoria. Come la maggior parte degli oggetti in OOP, ha proprietà . Inoltre, separatamente, ha una mappa degli attributi definiti sull'elemento (di solito proveniente dal markup letto dal browser per creare l'elemento). Alcune proprietà dell'elemento ottengono i loro valori iniziali da attributi con nomi uguali o simili ( valueottiene il suo valore iniziale dall'attributo "valore"; hrefottiene il suo valore iniziale dall'attributo "href", ma non è esattamente lo stesso valore; classNamedal attributo "class"). Altre proprietà ottengono i loro valori iniziali in altri modi: ad esempio, la parentNodeproprietà ottiene il suo valore in base all'elemento padre;style proprietà, che abbia o meno un attributo "style".

Consideriamo questa ancora in una pagina all'indirizzo http://example.com/testing.html:

<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>

Qualche arte ASCII gratuita (e tralasciando molte cose):

+ ------------------------------------------- +
| HTMLAnchorElement |
+ ------------------------------------------- +
| href: "http://example.com/foo.html" |
| nome: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| attributi: |
| href: "foo.html" |
| nome: "fooAnchor" |
| id: "fooAnchor" |
| classe: "test one" |
+ ------------------------------------------- +

Si noti che le proprietà e gli attributi sono distinti.

Ora, sebbene siano distinti, poiché tutto ciò si è evoluto anziché essere progettato da zero, un certo numero di proprietà riscrive l'attributo da cui derivano se le imposti. Ma non tutti lo fanno, e come puoi vedere hrefdall'alto, la mappatura non è sempre un "passaggio del valore", a volte c'è un'interpretazione implicata.

Quando parlo di proprietà come proprietà di un oggetto, non parlo in astratto. Ecco un codice non jQuery:

var link = document.getElementById('fooAnchor');
alert(link.href);                 // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"

(Questi valori sono come per la maggior parte dei browser; c'è qualche variazione.)

L' linkoggetto è una cosa reale e puoi vedere che esiste una vera distinzione tra l'accesso a una proprietà su di esso e l'accesso a un attributo .

Come ha detto Tim, la stragrande maggioranza delle volte, vogliamo lavorare con le proprietà. In parte è perché i loro valori (anche i loro nomi) tendono ad essere più coerenti tra i browser. Vogliamo principalmente lavorare con gli attributi quando non ci sono proprietà correlate ad esso (attributi personalizzati), o quando sappiamo che per quel particolare attributo, l'attributo e la proprietà non sono 1: 1 (come con hrefe "href" sopra) .

Le proprietà standard sono esposte nelle varie specifiche DOM:

Queste specifiche hanno indici eccellenti e raccomando di tenere a portata di mano i collegamenti; Li uso sempre.

Gli attributi personalizzati includono, ad esempio, qualsiasi data-xyzattributo che potresti mettere sugli elementi per fornire metadati al tuo codice (ora che è valido a partire da HTML5, purché ti attieni al data-prefisso). (Le versioni recenti di jQuery ti danno accesso agli data-xyzelementi tramite la datafunzione, ma quella funzione non è solo un accessorio per gli data-xyzattributi [fa sia più che meno di quello]; a meno che tu non abbia effettivamente bisogno delle sue caratteristiche, userei la attrfunzione per interagire con data-xyzattributo.)

La attrfunzione aveva una logica contorta attorno a ottenere ciò che pensavano volessi, piuttosto che ottenere letteralmente l'attributo. Ha unito i concetti. Il passaggio a proped attrera destinato a deconfigurarli. Brevemente in v1.6.0 jQuery è andato troppo in proposito, ma la funzionalità è stato subito aggiunto nuovamente per attrper gestire le situazioni comuni in cui le persone usano attrquando tecnicamente dovrebbero usare prop.


Wow. quel nuovo aggiornamento 1.6.1 annulla un po 'questa domanda .. (ma non molto) ma quel link sostanzialmente risponde ora
Naftali aka Neal

Non lo ha annullato per me, ho semplicemente corretto un bug usando jquery1.7 dove stavo impostando .attr ('class', 'bla') e non funzionava dove .prop ('className', 'bla' ) ha funzionato
PandaWood il

@PandaWood: .attr('class', 'bla')funziona come previsto per me in 1.7.0 , 1.7.1 e 1.7.2 su Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9 e Safari 5.
TJ Crowder

Grazie, ci deve essere qualcosa di specifico nel mio caso, fammi controllare questo e tornare con un caso di prova. Ma cambiando il codice come lo abbiamo ora, semplicemente "prop / className", invece di "attr" risolve un enorme bug per noi che ha colpito quando siamo passati da jquery1.4 a 1.7 - su tutti i browser
PandaWood

3
@TJCrowder re: .data- leggerà il valore predefinito dell'attributo, se presente, ma se ci scrivi, cambierà una proprietà nascosta dell'elemento e non aggiornerà l'attributo.
Alnitak,

250

Questo cambiamento è in arrivo da molto tempo per jQuery. Per anni, si sono accontentati di una funzione chiamata attr()che recuperava principalmente le proprietà DOM, non il risultato che ti aspetteresti dal nome. La separazione di attr()e prop()dovrebbe aiutare ad alleviare parte della confusione tra attributi HTML e proprietà DOM. $.fn.prop()prende la proprietà DOM specificata, mentre $.fn.attr()prende l'attributo HTML specificato.

Per comprendere appieno il loro funzionamento, ecco una spiegazione estesa sulla differenza tra attributi HTML e proprietà DOM .:

Attributi HTML

Sintassi:

<body onload="foo()">

Scopo: consente al markup di avere dati associati ad eventi, rendering e altri scopi.

Visualizzazione: Attributi HTML l'attributo di classe è mostrato qui sul corpo. È accessibile tramite il seguente codice:

var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");

Gli attributi vengono restituiti in forma di stringa e possono essere incoerenti da browser a browser. Tuttavia, possono essere vitali in alcune situazioni. Come esemplificato sopra, IE 8 Quirks Mode (e sotto) prevede il nome di una proprietà DOM in get / set / removeAttribute anziché il nome dell'attributo. Questo è uno dei tanti motivi per cui è importante conoscere la differenza.

Proprietà DOM

Sintassi:

document.body.onload = foo;

Scopo: dà accesso a proprietà che appartengono a nodi di elementi. Queste proprietà sono simili agli attributi, ma sono accessibili solo tramite JavaScript. Questa è una differenza importante che aiuta a chiarire il ruolo delle proprietà DOM. Si noti che gli attributi sono completamente diversi dalle proprietà , poiché questa assegnazione del gestore eventi è inutile e non riceverà l'evento (il corpo non ha un evento onload, ma solo un attributo onload).

visualizzazione: Proprietà DOM

Qui noterai un elenco di proprietà nella scheda "DOM" di Firebug. Queste sono proprietà DOM. Ne noterai immediatamente alcuni, come li hai già usati prima senza saperlo. I loro valori sono ciò che riceverai tramite JavaScript.

Documentazione

Esempio

HTML: <textarea id="test" value="foo"></textarea>

JavaScript: alert($('#test').attr('value'));

Nelle versioni precedenti di jQuery, questo restituisce una stringa vuota. In 1.6, restituisce il giusto valore, foo.

Senza avere dato un'occhiata al nuovo codice per entrambe le funzioni, posso dire con sicurezza che la confusione ha più a che fare con la differenza tra gli attributi HTML e le proprietà DOM, piuttosto che con il codice stesso. Spero che questo ti abbia chiarito alcune cose.

-Opaco


7
$.prop()ottiene proprietà DOM, $.attr()ottiene attributi HTML. Sto cercando di colmare il divario psicologicamente in modo da poter capire la differenza tra i due.

10
Ragazzo, ora sono confuso anche io. Quindi $('#test').prop('value')non restituisce nulla? Neanche .attr('checked')per una casella? Ma era solito? Ora dovresti cambiarlo in prop('checked')? Non capisco la necessità di questa distinzione: perché è importante distinguere tra attributi HTML e proprietà DOM? Qual è il caso d'uso comune che ha reso questo cambiamento "molto tempo a venire" ? Cosa c'è di sbagliato nell'astrarre la distinzione tra i due, dal momento che sembra che i loro casi d'uso si sovrappongano per lo più?
BlueRaja - Danny Pflughoeft,

5
@BlueRaja: perché c'è una grave differenza di fondo tra i due concetti che, se lo spazzoli sotto il tappeto come faceva jQuery, porta a guasti imprevisti. valueè uno dei casi più ovvi, poiché la valueproprietà ti darà il valore corrente di un campo, ma l' valueattributo ti darà il valore originale che è stato dichiarato value="..."nell'attributo, che in realtà è la defaultValueproprietà. (Anche se questo caso particolare viene nuovamente confuso da bug in IE <9.)
bobince

4
@BlueRaja: la risposta è ancora più complicata. :-) L'impostazione attr('value', ...)in jQuery <1.6 imposta la proprietà, quindi il valore corrente cambia e il valore predefinito no. In 1.6 imposta l'attributo, quindi in teoria il valore predefinito cambia e il valore corrente no. Tuttavia, ci sono (più) incoerenze del browser su cosa fa esattamente l'impostazione valuedell'attributo. In IE imposta anche il valore corrente; in alcuni browser imposta il valore corrente solo se il valore corrente non è già stato impostato prima. [piange]
bobince

1
Proprio come ha detto @Quentin, "Gli attributi sono definiti da HTML. Le proprietà sono definite da DOM." La versione più semplice che ho letto.
Alan Dong,

241

Una proprietà è nel DOM; un attributo si trova nel codice HTML che viene analizzato nel DOM.

Maggiori dettagli

Se si modifica un attributo, la modifica si rifletterà nel DOM (a volte con un nome diverso).

Esempio: la modifica classdell'attributo di un tag cambierà la classNameproprietà di quel tag nel DOM. Se non hai alcun attributo su un tag, hai ancora la proprietà DOM corrispondente con un valore vuoto o predefinito.

Esempio: sebbene il tag non abbia alcun classattributo, la proprietà DOM classNameesiste con un valore stringa vuoto.

modificare

Se si cambia l'uno, l'altro verrà modificato da un controller e viceversa. Questo controller non è in jQuery, ma nel codice nativo del browser.


Quindi questo significa che è meglio aggiornare l'attributo perché allora ti stai assicurando che l'attributo e la proprietà siano entrambi aggiornati e siano allineati?
Luca,

1
@Luke the DOM è la rappresentazione tecnica interna, il modello. Gli attributi HTML sono una rappresentazione esterna, una vista. Se si cambia l'uno, l'altro verrà modificato da un controller e viceversa.
yunzen

@HerrSerker Quindi sono entrambi sincronizzati tramite un controller? Presumo che questo sia solo all'interno dei metodi attr e prop di jQuery? Ecco una modifica del tuo violino in cui esploro di più - jsfiddle.net/v8wRy - e finora sembrano essere equivalenti.
Luca

3
"Se cambi l'uno, l'altro verrà modificato da un controller e viceversa. Questo controller non è in jQuery, ma nel codice nativo del browser." Questo non è vero per la maggior parte degli attributi / proprietà. Per la maggior parte è solo una traduzione unidirezionale in cui un attributo determina il valore iniziale della proprietà corrispondente. Le prime due risposte spiegano questo in dettaglio.
ᴠɪɴᴄᴇɴᴛ

@Vincent. Non vedo, dove le prime due risposte dicono qualcosa di contrario alla mia risposta. Naturalmente la maggior parte degli attributi sono i valori iniziali delle proprietà DOM corrispondenti. Ma sono reciprocamente dipendenti. Prova qualcosa come jQuery('p').prop('className', 'foo');nella console di Chrome e vedrai come ogni paragrafo ottiene l' classattributo thg di 'foo'. Ovviamente non nel codice sorgente, che proviene dal server. Questa è una costante
yunzen,

140

È solo la distinzione tra attributi HTML e oggetti DOM che provoca confusione. Per coloro che sono a proprio agio ad agire sulle proprietà native degli elementi DOM come un this.src this.value this.checkedecc, .propè un caloroso benvenuto in famiglia. Per altri, è solo un ulteriore livello di confusione. Risolviamolo.

Il modo più semplice per vedere la differenza tra .attred .propè il seguente esempio:

<input blah="hello">
  1. $('input').attr('blah'): ritorna 'hello'come previsto. Nessuna sorpresa qui.
  2. $('input').prop('blah'): restituisce undefined- perché sta tentando di farlo [HTMLInputElement].blah- e non esiste una tale proprietà su quell'oggetto DOM. Esiste solo nell'ambito come un attributo di quell'elemento cioè[HTMLInputElement].getAttribute('blah')

Ora cambiamo alcune cose in questo modo:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): ritorna 'apple'eh? Perché non "pera" in quanto questo è stato impostato per ultimo su quell'elemento. Poiché la proprietà è stata modificata sull'attributo input, non sull'elemento di input DOM stesso, praticamente funzionano quasi indipendentemente l'uno dall'altro.
  2. $('input').prop('blah'): ritorna 'pear'

La cosa di cui devi davvero fare attenzione è semplicemente non mescolare l'uso di questi per la stessa proprietà in tutta l'applicazione per il motivo sopra.

Guarda un violino che dimostra la differenza: http://jsfiddle.net/garreh/uLQXc/


.attrvs .prop:

Round 1: stile

<input style="font:arial;"/>
  • .attr('style') - restituisce stili incorporati per l'elemento corrispondente, ad es "font:arial;"
  • .prop('style') - restituisce un oggetto dichiarazione di stile, ad es CSSStyleDeclaration

Round 2: valore

<input value="hello" type="text"/>   

$('input').prop('value', 'i changed the value');
  • .attr('value') -- ritorna 'hello' *
  • .prop('value') -- ritorna 'i changed the value'

* Nota: jQuery per questo motivo ha un .val()metodo, internamente equivalente.prop('value')


@Neal perché fornisce un migliore riferimento alla struttura delle funzioni jquery. "$ ('input'). prop ('blah'): restituisce undefined - perché sta provando a fare [HTMLInputElement] .blah - e non esiste tale proprietà su quell'oggetto DOM. Esiste solo nell'ambito come attributo di quell'elemento, ad esempio [HTMLInputElement] .getAttribute ('blah') "
Uğur Gümüşhan

2
Sembra diverso dal doc, api.jquery.com/prop : "Il metodo .prop () dovrebbe essere usato per impostare disabilitato e controllato al posto del metodo .attr (). Il metodo .val () dovrebbe essere usato per ottenere e valore di impostazione ".
cigno

53

TL; DR

Utilizzare prop()sopra attr()nella maggior parte dei casi.

Una proprietà è lo stato corrente dell'elemento di input. Un attributo è il valore predefinito.

Una proprietà può contenere elementi di diversi tipi. Un attributo può contenere solo stringhe


1
se possibile, viene fornito un semplice esempio di ciò che stai dicendo e mostra anche quando usare prop() and when to go for attr(). in attesa di risposta :)
Mou,

36

Controllo sporco

Questo concetto fornisce un esempio in cui la differenza è osservabile: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Provalo:

  • fai clic sul pulsante. Entrambe le caselle sono state spuntate.
  • deseleziona entrambe le caselle di controllo.
  • fai di nuovo clic sul pulsante. È propstata selezionata solo la casella di controllo. SCOPPIO!

$('button').on('click', function() {
  $('#attr').attr('checked', 'checked')
  $('#prop').prop('checked', true)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>attr <input id="attr" type="checkbox"></label>
<label>prop <input id="prop" type="checkbox"></label>
<button type="button">Set checked attr and prop.</button>

Per alcuni attributi come disabledon button, l'aggiunta o la rimozione dell'attributo content disabled="disabled"attiva o disattiva sempre la proprietà (chiamata attributo IDL in HTML5) perché http://www.w3.org/TR/html5/forms.html#attr-fe-disabled dice:

L'attributo IDL disabilitato deve riflettere l'attributo del contenuto disabilitato.

quindi potresti cavartela, anche se è brutta poiché modifica HTML senza necessità.

Per altri attributi come checked="checked"on input type="checkbox", le cose si rompono, perché una volta che fai clic su di esso, diventa sporco, quindi l'aggiunta o la rimozione checked="checked"dell'attributo content non attiva più la verifica .

Questo è il motivo per cui dovresti usare principalmente .prop, poiché influenza direttamente la proprietà effettiva, invece di fare affidamento su effetti collaterali complessi della modifica dell'HTML.


Per completezza prova anche queste variazioni: 1) Prima di fare clic sul pulsante seleziona e quindi deseleziona la prima casella 2) (Per questo dovrai cambiare lo snippet) Assegna al primo input un checkedattributo:checked="checked"
ᴠɪɴᴄᴇɴᴛ

33

Tutto è nel documento :

La differenza tra attributi e proprietà può essere importante in situazioni specifiche. Prima di jQuery 1.6, il metodo .attr () a volte prendeva in considerazione i valori delle proprietà durante il recupero di alcuni attributi, il che poteva causare comportamenti incoerenti. A partire da jQuery 1.6, il metodo .prop () fornisce un modo per recuperare esplicitamente i valori delle proprietà, mentre .attr () recupera gli attributi.

Quindi usa prop!


2
Quindi ciò significa che quando passo a 1.6, molte cose si romperanno ??
Naftali aka Neal

No, è solo un comportamento incoerente, se funziona prima, funzionerà sempre con jQuery 1.6, è solo che il prop è più sicuro;)
Arnaud F.

6
Mi sembra di ricordare. $.attr()il recupero delle proprietà la maggior parte delle volte ci ho lavorato, non "a volte". La confusione causata da essa è ancora risonante oggi. Purtroppo, ho molti problemi a trovare una lettura definitiva sugli attributi HTML rispetto alle proprietà DOM, quindi potrei scrivere qui una risposta tra poco.

3
@ Arnaud-f Non è vero. Tutto il codice precedente alla 1.6 che utilizza attr ('controllato') per selezionare le caselle di controllo verrà ora rotto.
CaptSaltyJack

3
@Matt McDonald: Che tipo di "... difficoltà a trovare una lettura definitiva sugli attributi HTML rispetto alle proprietà DOM ..." vuoi dire? Le proprietà (riflesse e non) sono descritte nella specifica HTML DOM2 ; potrebbe anche essere necessario fare riferimento alle specifiche DOM2 e DOM3 .
TJ Crowder,

28

gli attributi sono nel tuo documento / file di testo HTML (== immagina che questo sia il risultato del tuo markup html analizzato), mentre le
proprietà sono nell'albero DOM HTML (== sostanzialmente una proprietà reale di alcuni oggetti in senso JS).

È importante sottolineare che molti di essi sono sincronizzati (se si aggiorna la classproprietà, anche l' classattributo in html verrà aggiornato; e altrimenti). Ma alcuni attributi possono essere sincronizzati con proprietà inattese - ad esempio, l' attributo checked corrisponde alla proprietà defaultChecked , quindi

  • il controllo manuale di una casella di controllo cambierà .prop('checked')valore, ma non cambierà .attr('checked')e .prop('defaultChecked')valori
  • anche l'impostazione $('#input').prop('defaultChecked', true)cambierà .attr('checked'), ma ciò non sarà visibile su un elemento.

La regola empirica è : il .prop()metodo dovrebbe essere usato per attributi / proprietà booleane e per proprietà che non esistono in HTML (come window.location). Tutti gli altri attributi (quelli che puoi vedere nel codice HTML) possono e devono continuare a essere manipolati con il .attr() metodo. ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )

Ed ecco una tabella che mostra dove .prop()è preferito (anche se .attr()può ancora essere usato).

tabella con utilizzo preferito


Perché a volte vorresti usare .prop () invece di .attr () dove quest'ultimo è ufficialmente consigliato?

  1. .prop()può restituire qualsiasi tipo - stringa, intero, booleano; mentre .attr()restituisce sempre una stringa.
  2. .prop()si dice che sia circa 2,5 volte più veloce di .attr().

qualcosa è stato cambiato, come questi: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class')o $('#myTextBox').prop('type', 'button'). E così via ...

@ Mr. Wolf, scusa, non capisco cosa intendi. cosa è cambiato'? la sintassi è sempre stata così.
Lakesare

Penso che la tabella nella tua risposta non sia necessaria. Perché .prop()funziona bene con tutte le proprietà. Non vuoi contrassegnare tutte le proprietà nella .prop()colonna, vero?

@ Mr. Wolf, penso che sia necessario, perché, come già detto, "mostra dove .prop()si preferisce (anche se .attr()può ancora essere usato)"
Lakesare

Di solito lo uso .attr()per definire un evento che .prop()non può. Come questo: $('.myDiv').attr('onclick', 'alert("Hello world!")'). Se cambi .attr()a .prop(), non funzionerà. Totalmente, penso che non ci sia motivo di usare .attr()per impostare o ottenere valore id/class/href/checked/src...... Nota che non dico che ti sbagli.

20

.attr():

  • Ottieni il valore di un attributo per il primo elemento nell'insieme di elementi corrispondenti.
  • Fornisce il valore dell'elemento come è stato definito nell'html al caricamento della pagina

.prop():

  • Ottieni il valore di una proprietà per il primo elemento nell'insieme di elementi corrispondenti.
  • Fornisce i valori aggiornati degli elementi che viene modificato tramite javascript / jquery

13

Di solito ti consigliamo di utilizzare le proprietà. Usa gli attributi solo per:

  1. Ottenere un attributo HTML personalizzato (poiché non è sincronizzato con una proprietà DOM).
  2. Ottenere un attributo HTML che non si sincronizza con una proprietà DOM, ad esempio ottenere il "valore originale" di un attributo HTML standard, come <input value="abc">.

7

attributes -> HTML

properties -> DOM


8
So cosa vuoi dire, ma HTML è un linguaggio di markup e DOM una rappresentazione creata dall'HTML. Un DOMElement ha sia attributi che proprietà .
t.niese,

@ t.niese, attirbutesanche una delle proprietà diDOM
NkS

La risposta breve è semplice.
Nabi KAZ,

6

Prima di jQuery 1.6, il attr()metodo a volte prendeva in considerazione i valori delle proprietà durante il recupero degli attributi, causando comportamenti piuttosto incoerenti.

L'introduzione del prop()metodo fornisce un modo per recuperare esplicitamente i valori delle proprietà, mentre .attr()recupera gli attributi.

I documenti:

jQuery.attr() Ottieni il valore di un attributo per il primo elemento nell'insieme di elementi corrispondenti.

jQuery.prop() Ottieni il valore di una proprietà per il primo elemento nell'insieme di elementi corrispondenti.


3

Promemoria delicato sull'uso prop(), esempio:

if ($("#checkbox1").prop('checked')) {
    isDelete = 1;
} else {
    isDelete = 0;
}

La funzione sopra è usata per verificare se checkbox1 è selezionato o meno, se selezionato: return 1; in caso contrario: return 0. Funzione prop () utilizzata qui come funzione GET.

if ($("#checkbox1").prop('checked', true)) {
    isDelete = 1;
} else {
    isDelete = 0;
}

La funzione sopra è usata per impostare checkbox1 da controllare e SEMPRE restituisce 1. Ora la funzione prop () usata come funzione SET.

Non fare casini.

P / S: quando sto controllando la proprietà Image src . Se src è vuoto, prop restituisce l'URL corrente della pagina (errato) e attr restituisce una stringa vuota (a destra).


Ti sbagli in questo esempio: <img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">. Dovrebbe funzionare e restituire la posizione dell'immagine.

2

Una cosa .attr()può fare che .prop()non può: influire sui selettori CSS

Ecco un problema che non ho visto nelle altre risposte.

Selettore CSS [name=value]

  • risponderà a .attr('name', 'value')
  • ma non sempre .prop('name', 'value')

.prop() interessa solo alcuni selettori di attributo

.attr() influenza tutti i selettori di attributo


0

1) Una proprietà è nel DOM; un attributo si trova nel codice HTML che viene analizzato nel DOM.

2) $ (elem) .attr ("checked") (1.6.1+) "checked" (String) Cambierà con lo stato della casella

3) $ (elem) .attr ("checked") (pre-1.6) true (Boolean) Modificato con stato checkbox

  • Per lo più vogliamo usare per oggetti DOM piuttosto che attributi personalizzati come data-img, data-xyz.

  • Anche alcune differenze quando si accede al checkboxvalore e href con attr()e prop()come cosa cambia con l'output DOM con prop()il collegamento completo da origine il Booleanvalore per la casella di controllo (pre-1.6)

  • Possiamo accedere agli elementi DOM solo con propaltri, quindi ci dàundefined


0

Ci sono alcune altre considerazioni in prop () vs attr ():

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked e defaultSelected..etc devono essere recuperati e impostati con il metodo .prop (). Questi non hanno attributi corrispondenti e sono solo proprietà.

  • Per la casella di controllo del tipo di input

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • Il metodo prop restituisce il valore booleano per controllato, selezionato, disabilitato, readOnly..etc mentre attr restituisce una stringa definita. Quindi, puoi usare direttamente .prop ('controllato') in if condition.

  • .attr () chiama .prop () internamente, quindi il metodo .attr () sarà leggermente più lento rispetto ad accedervi direttamente tramite .prop ().


-2

La risposta di Gary Hole è molto rilevante per risolvere il problema se il codice è scritto in questo modo

obj.prop("style","border:1px red solid;")

Poiché l' CSSStyleDeclarationoggetto restituisce la funzione prop , il codice sopra non funzionerà correttamente in alcuni browser (testato conIE8 with Chrome Frame Plugin nel mio caso).

Modificandolo così nel seguente codice

obj.prop("style").cssText = "border:1px red solid;"

problema risolto.

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.