jQuery attr vs prop?

JavascriptJqueryAttrProp

Javascript Problem Overview


Now this isn't just another What's the difference question, I have done some tests(http://jsfiddle.net/ZC3Lf/) modifying the prop and attr of <form action="/test/"></form>​ with the output being:

> 1) prop Modification test
> Prop: http://fiddle.jshell.net/test/1
> Attr: http://fiddle.jshell.net/test/1
> > 2) Attr Modification test
> Prop: http://fiddle.jshell.net/test/1
> Attr: /test/1
> > 3) Attr then Prop Modification test
> Prop: http://fiddle.jshell.net/test/11
> Attr: http://fiddle.jshell.net/test/11
> > 4) Prop then Attr Modification test
> Prop: http://fiddle.jshell.net/test/11
> Attr: http://fiddle.jshell.net/test/11

Now I am confused about a couple of things, as far as my knowledge goes:
Prop: The value in its current state after any modifications via JavaScript
Attr: The value as it was defined in the html on page load.

Now if this is correct,

  • Why does modifying the prop seem to make the action fully qualified, and conversely why does modifying the attribute not?
  • Why does modifying the prop in 1) modify the attribute, that one makes no sense to me?
  • Why does modifying the attr in 2) modify the property, are they meant to be linked that way?


Test Code

HTML

JavaScript

var element = $('form');
var property = 'action';

/*You should not need to modify below this line */

var body = $('body');
var original = element.attr(property);

body.append('<h1>Prop Modification test</h1>');
element.prop(property, element.prop(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

//reset
element.prop(property, original);
element.attr(property, original);

body.append('<h1>Attr Modification test</h1>');
element.attr(property, element.attr(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

//reset
element.prop(property, original);
element.attr(property, original);

body.append('<h1>Attr then Prop Modification test</h1>');
element.attr(property, element.attr(property) + 1);
element.prop(property, element.prop(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

//reset
element.prop(property, original);
element.attr(property, original);

body.append('<h1>Prop then Attr Modification test</h1>');
element.prop(property, element.prop(property) + 1);
element.attr(property, element.attr(property) + 1);

body.append('Prop: '+element.prop(property)+'<br />');
body.append('Attr: '+element.attr(property)+'<hr />');

Javascript Solutions


Solution 1 - Javascript

Unfortunately none of your links work :(

Some insight though, attr is for all attributes. prop is for properties.

In older jQuery versions (<1.6), we just had attr. To get to DOM properties such as nodeName, selectedIndex, or defaultValue you had to do something like:

var elem = $("#foo")[0];
if ( elem ) {
  index = elem.selectedIndex;
}

That sucked, so prop was added:

index = $("#foo").prop("selectedIndex");

This was great, but annoyingly this wasn't backward compatible, as:

<input type="checkbox" checked>

has no attribute of checked, but it does have a property called checked.

So, in the final build of 1.6, attr does also do prop so that things didn't break. Some people wanted this to be a clean break, but I think that the right decision was made as things didn't break all over the place!

Regarding:

> Prop: The value in it's current state after any modifications via JavaScript > > Attr: The value as it was defined in the html on page load.

This isn't always true, as many times the attribute is actually changed, but for properties such as checked, there isn't an attribute to change, so you need to use prop.

References:

http://blog.jquery.com/2011/05/03/jquery-16-released/

http://ejohn.org/blog/jquery-16-and-attr

Solution 2 - Javascript

There is a clear case to see differences between .prop and .attr

consider the HTML below :

<form name="form" action="#">
    <input type="text" name="action" value="myvalue" />
    <input type="submit" />
</form>
<pre id="return">
</pre>

and the JS below using jQuery :

$(document).ready(function(){
    $("#return").append("$('form').prop('action') : " + $('form').prop('action') + '\r\n');
    $("#return").append("$('form').attr('action') : " + $('form').attr('action') + '\r\n');
    $("#return").append("document.form.action : " + document.form.action);
});

creates the following output:

$('form').prop('action') : [object HTMLInputElement]
$('form').attr('action') : #
document.form.action : [object HTMLInputElement]

Solution 3 - Javascript

I have tried this

console.log(element.prop(property));
console.log(element.attr(property));

and it outputs as below

http://fiddle.jshell.net/test/
/test/ 

this may indicates that the action is normalized only when it is read with prop.

Solution 4 - Javascript

since jquery 1.6.1+ attr() returns/changes property like before 1.6. thus your tests do not make much sense.

be aware of minor changes in return values.

e.g.

attr(‘checked’): before 1.6 true/false is returend, since 1.6.1. “checked”/undefined is returned.

attr(‘selected’): before 1.6 true/false is returned, since 1.6.1 “selected”/undefined is returned

a detailed overview to this topic in german can be found here:

http://mabraham.de/jquery-prop-attr-val-richtig-verwenden/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHailwoodView Question on Stackoverflow
Solution 1 - JavascriptRich BradshawView Answer on Stackoverflow
Solution 2 - JavascriptSmasherHellView Answer on Stackoverflow
Solution 3 - JavascriptHaochengView Answer on Stackoverflow
Solution 4 - JavascriptMartin AbrahamView Answer on Stackoverflow