Vraag .prop () vs .attr ()
Zo jQuery 1.6 heeft de nieuwe functie prop()
.
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
of doen ze in dit geval hetzelfde?
En als ik do moet overschakelen op gebruik prop()
, al het oude attr()
oproepen zullen breken als ik overschakelen naar 1.6?
BIJWERKEN
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>
(zie ook deze viool: http://jsfiddle.net/maniator/JpUF2/)
De console logt het getAttribute
als een string, en de attr
als een string, maar de prop
als een CSSStyleDeclaration
, Waarom? En hoe beïnvloedt dat in de toekomst mijn codering?
2053
2018-05-03 19:33
oorsprong
antwoorden:
Update 1 november 2012
Mijn oorspronkelijke antwoord is specifiek van toepassing op jQuery 1.6. Mijn advies is hetzelfde gebleven, maar jQuery 1.6.1 veranderde iets: in het licht van de voorspelde stapel gebroken websites, het jQuery-team teruggekeerd attr()
naar iets dicht bij (maar niet precies hetzelfde als) zijn oude gedrag voor Booleaanse attributen. John Resig ook erover geblogd. Ik kan de moeilijkheid zien waarin ze zich bevonden, maar ben het nog steeds oneens met de aanbeveling om de voorkeur te geven attr()
.
Origineel antwoord
Als je jQuery en niet rechtstreeks de DOM hebt gebruikt, zou dit een verwarrende verandering kunnen zijn, hoewel het conceptueel beslist een verbetering is. Niet zo goed voor de baziljoenen van sites die jQuery gebruiken en die als gevolg van deze wijziging breken.
Ik zal de belangrijkste kwesties samenvatten:
- Meestal wil je dat
prop()
liever dan attr()
.
- In de meeste gevallen
prop()
doet wat attr()
gewend te doen. Gesprekken vervangen naar attr()
met prop()
in uw code zal over het algemeen werken.
- Eigenschappen zijn over het algemeen eenvoudiger om mee om te gaan dan attributen. Een attribuutwaarde mag alleen een tekenreeks zijn, terwijl een eigenschap van elk type kan zijn. Bijvoorbeeld de
checked
eigenschap is een Boolean, de style
eigenschap is een object met individuele eigenschappen voor elke stijl, de size
eigendom is een nummer.
- Wanneer zowel een eigenschap als een attribuut met dezelfde naam bestaat, zal het bijwerken van de ene gewoonlijk de andere bijwerken, maar dit is niet het geval voor bepaalde kenmerken van invoer, zoals
value
en checked
: voor deze kenmerken vertegenwoordigt de eigenschap altijd de huidige status terwijl het kenmerk (behalve in oude versies van IE) overeenkomt met de standaardwaarde / checkedness van de invoer (weerspiegeld in de defaultValue
/ defaultChecked
eigendom).
- Deze wijziging verwijdert een deel van de laag magische jQuery die voor attributen en eigenschappen vastzit, wat betekent dat ontwikkelaars van jQuery een beetje moeten leren over het verschil tussen eigenschappen en attributen. Dit is iets goeds.
Als je een jQuery-ontwikkelaar bent en door dit hele bedrijf wordt verward over eigenschappen en kenmerken, moet je een stapje terug doen en er iets over leren, aangezien jQuery niet langer zo hard probeert je tegen dit soort dingen te beschermen. Voor het gezaghebbende maar ietwat droge woord over dit onderwerp, zijn er de specificaties: DOM4, HTML DOM, DOM-niveau 2, DOM-niveau 3. De DOM-documentatie van Mozilla is geldig voor de meeste moderne browsers en is gemakkelijker te lezen dan de specificaties, dus je kunt ze vinden DOM-referentie nuttig. Er is een sectie over elementeigenschappen.
Als een voorbeeld van hoe eigenschappen eenvoudiger te hanteren zijn dan attributen, overweeg dan een selectievakje aanvankelijk aangevinkt. Hier zijn twee mogelijke stukjes geldige HTML om dit te doen:
<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">
Dus, hoe kom je erachter of het selectievakje is aangevinkt met jQuery? Kijk naar Stack Overflow en je zult vaak de volgende suggesties tegenkomen:
if ( $("#cb").attr("checked") === true ) {...}
if ( $("#cb").attr("checked") == "checked" ) {...}
if ( $("#cb").is(":checked") ) {...}
Dit is eigenlijk het eenvoudigste wat ter wereld te maken heeft met de checked
Boolean-eigenschap, die sinds 1995 foutloos in elke grote script-browser bestaat en werkte:
if (document.getElementById("cb").checked) {...}
De eigenschap maakt ook het in- of uitschakelen van het selectievakje triviaal:
document.getElementById("cb").checked = false
In jQuery 1.6 wordt dit ondubbelzinnig
$("#cb").prop("checked", false)
Het idee om de checked
attribuut voor het scripten van een selectievakje is nutteloos en onnodig. De woning is wat je nodig hebt.
- Het is niet duidelijk wat de juiste manier is om het selectievakje in of uit te schakelen, met behulp van de
checked
attribuut
- De kenmerkwaarde weerspiegelt de standaardwaarde in plaats van de huidige zichtbare staat (behalve in sommige oudere versies van IE, waardoor het nog moeilijker wordt). Het attribuut vertelt u niets over het feit of het selectievakje op de pagina is aangevinkt. Zien http://jsfiddle.net/VktA6/49/.
1734
2018-05-03 23:06
I denk Tim zei het vrij goed, maar laten we een stapje terug doen:
Een DOM-element is een object, een ding in het geheugen. Zoals de meeste objecten in OOP, wel eigenschappen. Het heeft ook, afzonderlijk, een kaart met de kenmerken die op het element zijn gedefinieerd (meestal afkomstig van de markup die de browser heeft gelezen om het element te maken). Sommige van de elementen eigenschappen haal hun eerste waarden van attributen met dezelfde of soortgelijke namen (value
krijgt de beginwaarde van het kenmerk "value"; href
krijgt de beginwaarde van het kenmerk 'href', maar het is niet precies dezelfde waarde; className
van het kenmerk "klasse"). Andere eigenschappen krijgen hun beginwaarden op andere manieren: bijvoorbeeld de parentNode
eigenschap krijgt zijn waarde op basis van wat het bovenliggende element is; een element heeft altijd een style
eigenschap, of deze nu een kenmerk "style" heeft of niet.
Laten we dit anker in een pagina bekijken http://example.com/testing.html
:
<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>
Enige gratis ASCII-kunst (en veel spullen weglaten):
+ ------------------------------------------- +
| HTMLAnchorElement |
+ ------------------------------------------- +
| href: "http://example.com/foo.html" |
| naam: "fooAnchor" |
| id: "fooAnchor" |
| className: "test één" |
| attributen: |
| href: "foo.html" |
| naam: "fooAnchor" |
| id: "fooAnchor" |
| klas: "test een" |
+ ------------------------------------------- +
Merk op dat de eigenschappen en attributen verschillend zijn.
Hoewel ze verschillend zijn, omdat dit allemaal is geëvolueerd in plaats van vanaf de grond af te zijn ontworpen, schrijven een aantal eigenschappen terug naar het attribuut waarvan ze zijn afgeleid als je ze hebt ingesteld. Maar niet allemaal, en zoals je kunt zien href
hierboven is de toewijzing niet altijd een straight "geef de waarde door", soms is er sprake van interpretatie.
Als ik het heb over eigenschappen als eigenschappen van een object, spreek ik niet in abstracto. Hier is wat niet-jQuery-code:
var link = document.getElementById('fooAnchor');
alert(link.href); // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"
(Deze waarden zijn van de meeste browsers, er is wat variatie.)
De link
object is echt, en je kunt zien dat er een echt verschil is tussen toegang tot een eigendom erop en toegang tot een attribuut.
Zoals Tim zei, de grote meerderheid van de tijd willen we met eigenschappen werken. Gedeeltelijk komt dat omdat hun waarden (zelfs hun namen) over het algemeen consistenter zijn in browsers. We willen meestal alleen met attributen werken als er geen eigenschap aan is gerelateerd (aangepaste attributen), of als we weten dat voor dat specifieke attribuut het attribuut en de eigenschap niet 1: 1 zijn (zoals bij href
en "href" hierboven).
De standaard eigenschappen zijn uiteengezet in de verschillende DOM-specificaties:
Deze specificaties hebben uitstekende indexen en ik raad aan om links naar hen bij de hand te houden; Ik gebruik ze altijd.
Aangepaste kenmerken kunnen bijvoorbeeld elk zijn data-xyz
attributen die u op elementen kunt plaatsen om metagegevens aan uw code te verstrekken (nu dat geldig is vanaf HTML5, zolang u zich aan de data-
voorvoegsel). (Recente versies van jQuery geven u toegang tot data-xyz
elementen via de data
functie, maar die functie is niet gewoon een accessor voor data-xyz
attributen [het doet zowel meer als minder dan dat]; tenzij je de functies echt nodig hebt, zou ik de attr
functie om mee te werken data-xyz
attribuut.)
De attr
De functie had enige ingewikkelde logica om te krijgen wat ze dachten dat je wilde, in plaats van letterlijk het attribuut te krijgen. Het bracht de concepten samen. Verhuizen naar prop
en attr
was bedoeld om ze te deblokkeren. Kort gezegd in v1.6.0 ging jQuery in dat opzicht te ver, maar met functionaliteit werd snel terug toegevoegd naar attr
om de veel voorkomende situaties te hanteren waar mensen gebruik van maken attr
wanneer ze technisch gezien zouden moeten gebruiken prop
.
621
2018-05-04 14:27
Deze verandering is lang aan de gang voor jQuery. Al jaren zijn ze tevreden met een functie met de naam attr()
die meestal DOM-eigenschappen heeft opgehaald, niet het resultaat dat je van de naam zou verwachten. De segregatie van attr()
en prop()
moet een deel van de verwarring tussen HTML-kenmerken en DOM-eigenschappen helpen verlichten. $.fn.prop()
pakt de opgegeven DOM-eigenschap terwijl $.fn.attr()
pakt het opgegeven HTML-kenmerk.
Om volledig te begrijpen hoe ze werken, vindt u hier een uitgebreide uitleg over het verschil tussen HTML-kenmerken en DOM-eigenschappen .:
HTML-kenmerken
Syntaxis:
<body onload="foo()">
Doel:
Toestaan dat markeringen gegevens bevatten die eraan zijn gekoppeld voor evenementen, weergave en andere doeleinden.
visualisatie:
Het kenmerk class wordt hier weergegeven op de body. Het is toegankelijk via de volgende code:
var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");
Attributen worden geretourneerd in stringvorm en kunnen van browser tot browser niet consistent zijn. In sommige situaties kunnen ze echter van levensbelang zijn. Zoals hierboven geïllustreerd, verwacht IE 8 Quirks Mode (en hieronder) de naam van een DOM-eigenschap in get / set / removeAttribute in plaats van de kenmerknaam. Dit is een van de vele redenen waarom het belangrijk is om het verschil te kennen.
DOM-eigenschappen
Syntaxis:
document.body.onload = foo;
Doel:
Geeft toegang tot eigenschappen die behoren tot elementknooppunten. Deze eigenschappen zijn vergelijkbaar met kenmerken, maar zijn alleen toegankelijk via JavaScript. Dit is een belangrijk verschil dat de rol van DOM-eigenschappen verduidelijkt. Houd er rekening mee dat attributen compleet verschillen van eigenschappen, omdat deze toewijzing van de gebeurtenishandler nutteloos is en de gebeurtenis niet ontvangt (instantie heeft geen onload-gebeurtenis, alleen een onload-attribuut).
visualisatie:

Hier ziet u een lijst met eigenschappen onder het tabblad "DOM" in Firebug. Dit zijn DOM-eigenschappen. Je zult er meteen een paar opmerken, omdat je ze eerder hebt gebruikt zonder het te weten. Hun waarden zijn wat u ontvangt via JavaScript.
Documentatie
Voorbeeld
HTML: <textarea id="test" value="foo"></textarea>
JavaScript: alert($('#test').attr('value'));
In eerdere versies van jQuery retourneert dit een lege tekenreeks. In 1.6 wordt de juiste waarde geretourneerd, foo
.
Zonder de nieuwe code voor beide functies te hebben bekeken, kan ik met vertrouwen zeggen dat de verwarring meer te maken heeft met het verschil tussen HTML-kenmerken en DOM-eigenschappen dan met de code zelf. Hopelijk heeft dit wat voor je opgeruimd.
-Mat
234
2018-05-03 20:05
Een eigenschap bevindt zich in de DOM; een attribuut is in de HTML die in de DOM is geparseerd.
Verdere details
Als u een kenmerk wijzigt, wordt de wijziging weergegeven in de DOM (soms met een andere naam).
Voorbeeld: de. Wijzigen class
attribuut van een tag zal de className
eigendom van die tag in de DOM.
Als u geen kenmerk op een tag hebt, heeft u nog steeds de bijbehorende DOM-eigenschap met een lege of standaardwaarde.
Voorbeeld: terwijl uw tag nee heeft class
attribuut, de eigenschap DOM className
bestaat met een lege reekswaarde.
Bewerk
Als u de ene wijzigt, wordt de andere gewijzigd door een controller en omgekeerd.
Deze controller bevindt zich niet in jQuery, maar in de native code van de browser.
232
2017-09-27 16:55
Het is gewoon het verschil tussen HTML-kenmerken en DOM-objecten die voor verwarring zorgen. Voor diegenen die zich op hun gemak voelen met de DOM-elementen, moeten native properties zoals een this.src
this.value
this.checked
enz, .prop
is een zeer warm welkom in de familie. Voor anderen is het slechts een extra laag verwarring. Laten we dat duidelijk maken.
De eenvoudigste manier om het verschil tussen te zien .attr
en .prop
is het volgende voorbeeld:
<input blah="hello">
$('input').attr('blah')
: komt terug 'hello'
zoals verwacht. Geen verrassingen hier.
$('input').prop('blah')
: komt terug undefined
- omdat het probeert te doen [HTMLInputElement].blah
- en er bestaat geen dergelijke eigenschap op dat DOM-object. Het bestaat alleen in de scope als een attribuut van dat element, d.w.z. [HTMLInputElement].getAttribute('blah')
Nu veranderen we een paar dingen zoals:
$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
$('input').attr('blah')
: komt terug 'apple'
eh? Waarom niet "peren", omdat dit als laatste op dat element is ingesteld. Omdat de eigenschap is gewijzigd op het invoerattribuut, niet het DOM-invoerelement zelf - ze werken in principe bijna onafhankelijk van elkaar.
$('input').prop('blah')
: komt terug 'pear'
Het ding waar je echt voorzichtig mee moet zijn, is gewoon meng het gebruik van deze niet voor dezelfde eigenschap tijdens uw toepassing om de bovenstaande reden.
Zie een viool die het verschil demonstreert: http://jsfiddle.net/garreh/uLQXc/
.attr
vs .prop
:
Ronde 1: stijl
<input style="font:arial;"/>
.attr('style')
- retourneert inline stijlen voor het overeenkomende element, d.w.z. "font:arial;"
.prop('style')
- geeft een stijlaangiftevoorwerp terug CSSStyleDeclaration
Ronde 2: waarde
<input value="hello" type="text"/>
$('input').prop('value', 'i changed the value');
.attr('value')
-- komt terug 'hello'
*
.prop('value')
-- komt terug 'i changed the value'
* Opmerking: jQuery heeft om deze reden een .val()
methode, die intern gelijkwaardig is aan .prop('value')
131
2018-05-19 10:18
TL; DR
Gebruik prop()
over- attr()
in de meeste gevallen.
EEN eigendom is de huidige status van het invoerelement. Een attribuut is de standaardwaarde.
Een eigenschap kan dingen van verschillende typen bevatten. Een kenmerk kan alleen strings bevatten
48
2017-07-16 09:45
Vuile controle
Dit concept is een voorbeeld waarbij het verschil waarneembaar is: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty
Probeer het:
- Klik op de knop. Beide selectievakjes zijn aangevinkt.
- Schakel beide selectievakjes uit.
- klik opnieuw op de knop. Alleen de
prop
selectievakje is aangevinkt. BANG!
$('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>
Voor sommige attributen zoals disabled
op button
, het toevoegen of verwijderen van het inhoudsattribuut disabled="disabled"
schakelt altijd de eigenschap (genaamd IDL-attribuut in HTML5) in omdat http://www.w3.org/TR/html5/forms.html#attr-fe-disabled zegt:
Het uitgeschakelde IDL-kenmerk moet het uitgeschakelde content-kenmerk weerspiegelen.
dus je kunt ermee wegkomen, hoewel het lelijk is omdat het HTML zonder noodzaak aanpast.
Voor andere kenmerken zoals checked="checked"
op input type="checkbox"
, dingen breken, omdat als je erop klikt, het vies wordt, en dan het toevoegen of verwijderen van checked="checked"
inhoudsattribuut schakelt check niet meer uit.
Dit is waarom je het meest zou moeten gebruiken .prop
omdat het de effectieve eigenschap rechtstreeks beïnvloedt, in plaats van te vertrouwen op complexe bijwerkingen.
34
2017-07-06 11:43
Alles zit in het document:
Het verschil tussen kenmerken en eigenschappen kan belangrijk zijn in specifieke situaties. Vóór jQuery 1.6 hield de .attr () -methode soms rekening met eigenschapswaarden bij het ophalen van sommige kenmerken, wat tot inconsistent gedrag kon leiden. Vanaf jQuery 1.6 biedt de methode .prop () een manier om eigenschapwaarden expliciet op te halen, terwijl .attr () alleen kenmerken ophaalt.
Gebruik dus prop!
32
2018-05-03 19:35
attributen staan in je HTML tekstdocument / bestand (== stel je voor dat dit het resultaat is van je html-markup die is geparseerd), terwijl
eigenschappenzijn in HTML DOM-boom (== in feite een actuele eigenschap van een object in JS-zin).
Belangrijk is dat veel van hen worden gesynchroniseerd (als u werkt class
eigendom, class
attribuut in html zal ook worden bijgewerkt; en anders). Maar sommige kenmerken kunnen worden gesynchroniseerd met onverwachte eigenschappen - bijvoorbeeld attribuut checked
komt overeen met eigendom defaultChecked
, zodat
- het handmatig aanvinken van een selectievakje zal veranderen
.prop('checked')
waarde, maar zal niet veranderen .attr('checked')
en .prop('defaultChecked')
waarden
- omgeving
$('#input').prop('defaultChecked', true)
zal ook veranderen .attr('checked')
, maar dit zal niet zichtbaar zijn op een element.
Vuistregel is: .prop()
methode moet worden gebruikt voor booleaanse attributen / eigenschappen en voor eigenschappen die niet bestaan in html
(zoals window.location). Alle andere kenmerken (die u kunt zien in
de html) kan en zou moeten blijven worden gemanipuleerd met de .attr()
methode. (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/)
En hier is een tabel die laat zien waar .prop()
heeft de voorkeur (hoewel .attr()
kan nog steeds worden gebruikt).

Waarom zou u soms .prop () in plaats van .attr () willen gebruiken waar dit officieel is geadviseerd?
.prop()
kan elk type teruggeven - string, integer, boolean; terwijl .attr()
geeft altijd een string terug.
.prop()
is naar verluidt ongeveer 2,5 keer sneller dan .attr()
.
26
2018-06-12 05:56
.attr()
:
- Verkrijg de waarde van een attribuut voor het eerste element in de verzameling overeenkomende elementen.
- Geeft de waarde van het element zoals het werd gedefinieerd in de HTML-code bij het laden van de pagina
.prop()
:
- Verkrijg de waarde van a eigendom voor het eerste element in de verzameling overeenkomende elementen.
- Geeft de bijgewerkte waarden van elementen die is gewijzigd via javascript / jQuery
18
2017-12-08 09:14
Meestal wil je eigenschappen gebruiken.
Gebruik attributen alleen voor:
- Een aangepast HTML-kenmerk krijgen (omdat het niet is gesynchroniseerd met een DOM-eigenschap).
- Een HTML-kenmerk krijgen dat niet wordt gesynchroniseerd met een DOM-eigenschap, bijvoorbeeld verkrijg de "oorspronkelijke waarde" van een standaard HTML-kenmerk, zoals
<input value="abc">.
13
2018-02-02 20:36