So jQuery 1.6 has the new function prop().
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
or in this case do they do the same thing?
And if I do have to switch to using prop(), all the old attr() calls will break if i switch to 1.6?
UPDATE
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>
(see also this fiddle: http://jsfiddle.net/maniator/JpUF2/)
The console logs the getAttribute as a string, and the attr as a string, but the prop as a CSSStyleDeclaration, Why? And how does that affect my coding in the future?
Update 1 November 2012
My original answer applies specifically to jQuery 1.6. My advice remains the same but jQuery 1.6.1 changed things slightly: in the face of the predicted pile of broken websites, the jQuery team reverted attr() to something close to (but not exactly the same as) its old behaviour for Boolean attributes. John Resig also blogged about it. I can see the difficulty they were in but still disagree with his recommendation to prefer attr().
Original answer
If you've only ever used jQuery and not the DOM directly, this could be a confusing change, although it is definitely an improvement conceptually. Not so good for the bazillions of sites using jQuery that will break as a result of this change though.
I'll summarize the main issues:
You usually want prop() rather than attr().
In the majority of cases, prop() does what attr() used to do. Replacing calls to attr() with prop() in your code will generally work.
Properties are generally simpler to deal with than attributes. An attribute value may only be a string whereas a property can be of any type. For example, the checked property is a Boolean, the style property is an object with individual properties for each style, the size property is a number.
Where both a property and an attribute with the same name exists, usually updating one will update the other, but this is not the case for certain attributes of inputs, such as value and checked: for these attributes, the property always represents the current state while the attribute (except in old versions of IE) corresponds to the default value/checkedness of the input (reflected in the defaultValue / defaultChecked property).
This change removes some of the layer of magic jQuery stuck in front of attributes and properties, meaning jQuery developers will have to learn a bit about the difference between properties and attributes. This is a good thing.
If you're a jQuery developer and are confused by this whole business about properties and attributes, you need to take a step back and learn a little about it, since jQuery is no longer trying so hard to shield you from this stuff. For the authoritative but somewhat dry word on the subject, there's the specs: DOM4, HTML DOM, DOM Level 2, DOM Level 3. Mozilla's DOM documentation is valid for most modern browsers and is easier to read than the specs, so you may find their DOM reference helpful. There's a section on element properties.
As an example of how properties are simpler to deal with than attributes, consider a checkbox that is initially checked. Here are two possible pieces of valid HTML to do this:
<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">
So, how do you find out if the checkbox is checked with jQuery? Look on Stack Overflow and you'll commonly find the following suggestions:
if ( $("#cb").attr("checked") === true ) {...}
if ( $("#cb").attr("checked") == "checked" ) {...}
if ( $("#cb").is(":checked") ) {...}
This is actually the simplest thing in the world to do with the checked Boolean property, which has existed and worked flawlessly in every major scriptable browser since 1995:
if (document.getElementById("cb").checked) {...}
The property also makes checking or unchecking the checkbox trivial:
document.getElementById("cb").checked = false
In jQuery 1.6, this unambiguously becomes
$("#cb").prop("checked", false)
The idea of using the checked attribute for scripting a checkbox is unhelpful and unnecessary. The property is what you need.
It's not obvious what the correct way to check or uncheck the checkbox is using the checked attribute
The attribute value reflects the default rather than the current visible state (except in some older versions of IE, thus making things still harder). The attribute tells you nothing about the whether the checkbox on the page is checked. See http://jsfiddle.net/VktA6/49/.
I think Tim said it quite well, but let's step back:
A DOM element is an object, a thing in memory. Like most objects in OOP, it has properties. It also, separately, has a map of the attributes defined on the element (usually coming from the markup that the browser read to create the element). Some of the element's properties get their initial values from attributes with the same or similar names (value gets its initial value from the "value" attribute; href gets its initial value from the "href" attribute, but it's not exactly the same value; className from the "class" attribute). Other properties get their initial values in other ways: For instance, the parentNode property gets its value based on what its parent element is; an element always has a style property, whether it has a "style" attribute or not.
Let's consider this anchor in a page at http://example.com/testing.html:
<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>
Some gratuitous ASCII art (and leaving out a lot of stuff):
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| HTMLAnchorElement |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| href: "http://example.com/foo.html" |
| name: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| attributes: |
| href: "foo.html" |
| name: "fooAnchor" |
| id: "fooAnchor" |
| class: "test one" |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
Note that the properties and attributes are distinct.
Now, although they are distinct, because all of this evolved rather than being designed from the ground up, a number of properties write back to the attribute they derived from if you set them. But not all do, and as you can see from href above, the mapping is not always a straight "pass the value on", sometimes there's interpretation involved.
When I talk about properties being properties of an object, I'm not speaking in the abstract. Here's some non-jQuery code:
var link = document.getElementById('fooAnchor');
alert(link.href); // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"
(Those values are as per most browsers; there's some variation.)
The link object is a real thing, and you can see there's a real distinction between accessing a property on it, and accessing an attribute.
As Tim said, the vast majority of the time, we want to be working with properties. Partially that's because their values (even their names) tend to be more consistent across browsers. We mostly only want to work with attributes when there is no property related to it (custom attributes), or when we know that for that particular attribute, the attribute and the property are not 1:1 (as with href and "href" above).
The standard properties are laid out in the various DOM specs:
DOM2 HTML (largely obsolete, see the HTML spec instead)
DOM2 Core (obsolete)
DOM3 Core (obsolete)
DOM4
These specs have excellent indexes and I recommend keeping links to them handy; I use them all the time.
Custom attributes would include, for instance, any data-xyz attributes you might put on elements to provide meta-data to your code (now that that's valid as of HTML5, as long as you stick to the data- prefix). (Recent versions of jQuery give you access to data-xyz elements via the data function, but that function is not just an accessor for data-xyz attributes [it does both more and less than that]; unless you actually need its features, I'd use the attr function to interact with data-xyz attribute.)
The attr function used to have some convoluted logic around getting what they thought you wanted, rather than literally getting the attribute. It conflated the concepts. Moving to prop and attr was meant to de-conflate them. Briefly in v1.6.0 jQuery went too far in that regard, but functionality was quickly added back to attr to handle the common situations where people use attr when technically they should use prop.
This change has been a long time coming for jQuery. For years, they've been content with a function named attr() that mostly retrieved DOM properties, not the result you'd expect from the name. The segregation of attr() and prop() should help alleviate some of the confusion between HTML attributes and DOM properties. $.fn.prop() grabs the specified DOM property, while $.fn.attr() grabs the specified HTML attribute.
To fully understand how they work, here's an extended explanation on the difference between HTML attributes and DOM properties.:
HTML Attributes
Syntax:
<body onload="foo()">
Purpose:
Allows markup to have data associated with it for events, rendering, and other purposes.
Visualization:
The class attribute is shown here on the body. It's accessible through the following code:
var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");
Attributes are returned in string form and can be inconsistent from browser to browser. However, they can be vital in some situations. As exemplified above, IE 8 Quirks Mode (and below) expects the name of a DOM property in get/set/removeAttribute instead of the attribute name. This is one of many reasons why it's important to know the difference.
DOM Properties
Syntax:
document.body.onload = foo;
Purpose:
Gives access to properties that belong to element nodes. These properties are similar to attributes, but are only accessible through JavaScript. This is an important difference that helps clarify the role of DOM properties. Please note that attributes are completely different from properties, as this event handler assignment is useless and won't receive the event (body doesn't have an onload event, only an onload attribute).
Visualization:
Here, you'll notice a list of properties under the "DOM" tab in Firebug. These are DOM properties. You'll immediately notice quite a few of them, as you'll have used them before without knowing it. Their values are what you'll be receiving through JavaScript.
Documentation
JavaScript: The Definitive Guide by
David Flanagan
HTML Attributes,
Mozilla Dev Center
DOM Element Properties, Mozilla Dev Center
Example
HTML: <textarea id="test" value="foo"></textarea>
JavaScript: alert($('#test').attr('value'));
In earlier versions of jQuery, this returns an empty string. In 1.6, it returns the proper value, foo.
Without having glanced at the new code for either function, I can say with confidence that the confusion has more to do with the difference between HTML attributes and DOM properties, than with the code itself. Hopefully, this cleared some things up for you.
-Matt
A property is in the DOM; an attribute is in the HTML that is parsed into the DOM.
Further detail
If you change an attribute, the change will be reflected in the DOM (sometimes with a different name).
Example: Changing the class attribute of a tag will change the className property of that tag in the DOM (That's because class is already used).
If you have no attribute on a tag, you still have the corresponding DOM property with an empty or a default value.
Example: While your tag has no class attribute, the DOM property className does exist with a empty string value.
edit
If you change the one, the other will be changed by a controller, and vice versa.
This controller is not in jQuery, but in the browser's native code.
It's just the distinction between HTML attributes and DOM objects that causes a confusion. For those that are comfortable acting on the DOM elements native properties such a this.src this.value this.checked etc, .prop is a very warm welcome to the family. For others, it's just an added layer of confusion. Let's clear that up.
The easiest way to see the difference between .attr and .prop is the following example:
<input blah="hello">
$('input').attr('blah'): returns 'hello' as expected. No suprises here.
$('input').prop('blah'): returns undefined -- because it's trying to do [HTMLInputElement].blah -- and no such property on that DOM object exists. It only exists in the scope as an attribute of that element i.e. [HTMLInputElement].getAttribute('blah')
Now we change a few things like so:
$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
$('input').attr('blah'): returns 'apple' eh? Why not "pear" as this was set last on that element. Because the property was changed on the input attribute, not the DOM input element itself -- they basically almost work independently of each other.
$('input').prop('blah'): returns 'pear'
The thing you really need to be careful with is just do not mix the usage of these for the same property throughout your application for the above reason.
See a fiddle demonstrating the difference: http://jsfiddle.net/garreh/uLQXc/
.attr vs .prop:
Round 1: style
<input style="font:arial;"/>
.attr('style') -- returns inline styles for the matched element i.e. "font:arial;"
.prop('style') -- returns an style declaration object i.e. CSSStyleDeclaration
Round 2: value
<input value="hello" type="text"/>
$('input').prop('value', 'i changed the value');
.attr('value') -- returns 'hello' *
.prop('value') -- returns 'i changed the value'
* Note: jQuery for this reason has a .val() method, which internally is equivalent to .prop('value')
TL;DR
Use prop() over attr() in the majority of cases.
A property is the current state of the input element. An attribute is the default value.
A property can contain things of different types. An attribute can only contain strings
Dirty checkedness
This concept provides an example where the difference is observable: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty
Try it out:
click the button. Both checkboxes got checked.
uncheck both checkboxes.
click the button again. Only the prop checkbox got checked. 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>
For some attributes like disabled on button, adding or removing the content attribute disabled="disabled" always toggles the property (called IDL attribute in HTML5) because http://www.w3.org/TR/html5/forms.html#attr-fe-disabled says:
The disabled IDL attribute must reflect the disabled content attribute.
so you might get away with it, although it is ugly since it modifies HTML without need.
For other attributes like checked="checked" on input type="checkbox", things break, because once you click on it, it becomes dirty, and then adding or removing the checked="checked" content attribute does not toggle checkedness anymore.
This is why you should use mostly .prop, as it affects the effective property directly, instead of relying on complex side-effects of modifying the HTML.
All is in the doc:
The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
So use prop!
attributes are in your HTML text document/file (== imagine this is the result of your html markup parsed), whereas
properties are in HTML DOM tree (== basically an actual property of some object in JS sense).
Importantly, many of them are synced (if you update class property, class attribute in html will also be updated; and otherwise). But some attributes may be synced to unexpected properties - eg, attribute checked corresponds to property defaultChecked, so that
manually checking a checkbox will change .prop('checked') value, but will not change .attr('checked') and .prop('defaultChecked') values
setting $('#input').prop('defaultChecked', true) will also change .attr('checked'), but this will not be visible on an element.
Rule of thumb is: .prop() method should be used for boolean attributes/properties and for properties which do not exist in html
(such as window.location). All other attributes (ones you can see in
the html) can and should continue to be manipulated with the .attr()
method. (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/)
And here is a table that shows where .prop() is preferred (even though .attr() can still be used).
Why would you sometimes want to use .prop() instead of .attr() where latter is officially adviced?
.prop() can return any type - string, integer, boolean; while .attr() always returns a string.
.prop() is said to be about 2.5 times faster than .attr().
.attr():
Get the value of an attribute for the first element in the set of matched elements.
Gives you the value of element as it was defined in the html on page load
.prop():
Get the value of a property for the first element in the set of matched elements.
Gives the updated values of elements which is modified via javascript/jquery
Usually you'll want to use properties.
Use attributes only for:
Getting a custom HTML attribute (since it's not synced with a DOM property).
Getting a HTML attribute that doesn't sync with a DOM property, e.g. get the "original value" of a standard HTML attribute, like <input value="abc">.
attributes -> HTML
properties -> DOM
Before jQuery 1.6 , the attr() method sometimes took property values into account when retrieving attributes, this caused rather inconsistent behavior.
The introduction of the prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
The Docs:
jQuery.attr()
Get the value of an attribute for the first element in the set of matched elements.
jQuery.prop()
Get the value of a property for the first element in the set of matched elements.
One thing .attr() can do that .prop() can't: affect CSS selectors
Here's an issue I didn't see in the other answers.
CSS selector [name=value]
will respond to .attr('name', 'value')
but not always to .prop('name', 'value')
.prop() affects only a few attribute-selectors
input[name] (thanks #TimDown)
.attr() affects all attribute-selectors
input[value]
input[naame]
span[name]
input[data-custom-attribute] (neither will .data('custom-attribute') affect this selector)
Gently reminder about using prop(), example:
if ($("#checkbox1").prop('checked')) {
isDelete = 1;
} else {
isDelete = 0;
}
The function above is used to check if checkbox1 is checked or not, if checked: return 1; if not: return 0. Function prop() used here as a GET function.
if ($("#checkbox1").prop('checked', true)) {
isDelete = 1;
} else {
isDelete = 0;
}
The function above is used to set checkbox1 to be checked and ALWAYS return 1. Now function prop() used as a SET function.
Don't mess up.
P/S: When I'm checking Image src property. If the src is empty, prop return the current URL of the page (wrong), and attr return empty string (right).
1) A property is in the DOM; an attribute is in the HTML that is
parsed into the DOM.
2) $( elem ).attr( "checked" ) (1.6.1+) "checked" (String) Will
change with checkbox state
3) $( elem ).attr( "checked" ) (pre-1.6) true (Boolean) Changed
with checkbox state
Mostly we want to use for DOM object rather then custom attribute
like data-img, data-xyz.
Also some of difference when accessing checkbox value and href
with attr() and prop() as thing change with DOM output with
prop() as full link from origin and Boolean value for checkbox
(pre-1.6)
We can only access DOM elements with prop other then it gives undefined
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>prop demo</title>
<style>
p {
margin: 20px 0 0;
}
b {
color: blue;
}
</style>
</head>
<body>
<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>
<script>
$("input").change(function() {
var $input = $(this);
$("p").html(
".attr( \"checked\" ): <b>" + $input.attr("checked") + "</b><br>" +
".prop( \"checked\" ): <b>" + $input.prop("checked") + "</b><br>" +
".is( \":checked\" ): <b>" + $input.is(":checked")) + "</b>";
}).change();
</script>
</body>
</html>
There are few more considerations in prop() vs attr():
selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, and defaultSelected..etc should be retrieved and set with the .prop() method. These do not have corresponding attributes and are only properties.
For input type checkbox
.attr('checked') //returns checked
.prop('checked') //returns true
.is(':checked') //returns true
prop method returns Boolean value for checked, selected, disabled,
readOnly..etc while attr returns defined string. So, you can directly
use .prop(‘checked’) in if condition.
.attr() calls .prop() internally so .attr() method will be slightly
slower than accessing them directly through .prop().
Gary Hole answer is very relevant to solve the problem if the code is written in such way
obj.prop("style","border:1px red solid;")
Since the prop function return CSSStyleDeclaration object, above code will not working properly in some browser(tested with IE8 with Chrome Frame Plugin in my case).
Thus changing it into following code
obj.prop("style").cssText = "border:1px red solid;"
solved the problem.
Related
After the changes made in jQuery 1.6.1, I have been trying to define the difference between properties and attributes in HTML.
Looking at the list on the jQuery 1.6.1 release notes (near the bottom), it seems one can classify HTML properties and attributes as follows:
Properties: All which either has a boolean value or that is UA calculated such as selectedIndex.
Attributes: 'Attributes' that can be added to a HTML element which is neither boolean nor containing a UA generated value.
Thoughts?
When writing HTML source code, you can define attributes on your HTML elements. Then, once the browser parses your code, a corresponding DOM node will be created. This node is an object, and therefore it has properties.
For instance, this HTML element:
<input type="text" value="Name:">
has 2 attributes (type and value).
Once the browser parses this code, a HTMLInputElement object will be created, and this object will contain dozens of properties like: accept, accessKey, align, alt, attributes, autofocus, baseURI, checked, childElementCount, childNodes, children, classList, className, clientHeight, etc.
For a given DOM node object, properties are the properties of that object, and attributes are the elements of the attributes property of that object.
When a DOM node is created for a given HTML element, many of its properties relate to attributes with the same or similar names, but it's not a one-to-one relationship. For instance, for this HTML element:
<input id="the-input" type="text" value="Name:">
the corresponding DOM node will have id,type, and value properties (among others):
The id property is a reflected property for the id attribute: Getting the property reads the attribute value, and setting the property writes the attribute value. id is a pure reflected property, it doesn't modify or limit the value.
The type property is a reflected property for the type attribute: Getting the property reads the attribute value, and setting the property writes the attribute value. type isn't a pure reflected property because it's limited to known values (e.g., the valid types of an input). If you had <input type="foo">, then theInput.getAttribute("type") gives you "foo" but theInput.type gives you "text".
In contrast, the value property doesn't reflect the value attribute. Instead, it's the current value of the input. When the user manually changes the value of the input box, the value property will reflect this change. So if the user inputs "John" into the input box, then:
theInput.value // returns "John"
whereas:
theInput.getAttribute('value') // returns "Name:"
The value property reflects the current text-content inside the input box, whereas the value attribute contains the initial text-content of the value attribute from the HTML source code.
So if you want to know what's currently inside the text-box, read the property. If you, however, want to know what the initial value of the text-box was, read the attribute. Or you can use the defaultValue property, which is a pure reflection of the value attribute:
theInput.value // returns "John"
theInput.getAttribute('value') // returns "Name:"
theInput.defaultValue // returns "Name:"
There are several properties that directly reflect their attribute (rel, id), some are direct reflections with slightly-different names (htmlFor reflects the for attribute, className reflects the class attribute), many that reflect their attribute but with restrictions/modifications (src, href, disabled, multiple), and so on. The spec covers the various kinds of reflection.
After reading Sime Vidas's answer, I searched more and found a very straight-forward and easy-to-understand explanation in the angular docs.
HTML attribute vs. DOM property
-------------------------------
Attributes are defined by HTML. Properties are defined by the DOM
(Document Object Model).
A few HTML attributes have 1:1 mapping to properties. id is one
example.
Some HTML attributes don't have corresponding properties. colspan is
one example.
Some DOM properties don't have corresponding attributes. textContent
is one example.
Many HTML attributes appear to map to properties ... but not in the
way you might think!
That last category is confusing until you grasp this general rule:
Attributes initialize DOM properties and then they are done. Property
values can change; attribute values can't.
For example, when the browser renders <input type="text" value="Bob">,
it creates a corresponding DOM node with a value property initialized
to "Bob".
When the user enters "Sally" into the input box, the DOM element value
property becomes "Sally". But the HTML value attribute remains
unchanged as you discover if you ask the input element about that
attribute: input.getAttribute('value') returns "Bob".
The HTML attribute value specifies the initial value; the DOM value
property is the current value.
The disabled attribute is another peculiar example. A button's
disabled property is false by default so the button is enabled. When
you add the disabled attribute, its presence alone initializes the
button's disabled property to true so the button is disabled.
Adding and removing the disabled attribute disables and enables the
button. The value of the attribute is irrelevant, which is why you
cannot enable a button by writing <button disabled="false">Still Disabled</button>.
Setting the button's disabled property disables or enables the button. The value of the property matters.
The HTML attribute and the DOM property are not the same thing, even
when they have the same name.
The answers already explain how attributes and properties are handled differently, but I really would like to point out how totally insane this is. Even if it is to some extent the spec.
It is crazy, to have some of the attributes (e.g. id, class, foo, bar) to retain only one kind of value in the DOM, while some attributes (e.g. checked, selected) to retain two values; that is, the value "when it was loaded" and the value of the "dynamic state". (Isn't the DOM supposed to be to represent the state of the document to its full extent?)
It is absolutely essential, that two input fields, e.g. a text and a checkbox behave the very same way. If the text input field does not retain a separate "when it was loaded" value and the "current, dynamic" value, why does the checkbox? If the checkbox does have two values for the checked attribute, why does it not have two for its class and id attributes?
If you expect to change the value of a text *input* field, and you expect the DOM (i.e. the "serialized representation") to change, and reflect this change, why on earth would you not expect the same from an input field of type checkbox on the checked attribute?
The differentiation, of "it is a boolean attribute" just does not make any sense to me, or is, at least not a sufficient reason for this.
Difference HTML properties and attributes:
Let's first look at the definitions of these words before evaluating what the difference is in HTML:
English definition:
Attributes are referring to additional information of an object.
Properties are describing the characteristics of an object.
In HTML context:
When the browser parses the HTML, it creates a tree data structure wich basically is an in memory representation of the HTML. It the tree data structure contains nodes which are HTML elements and text. Attributes and properties relate to this is the following manner:
Attributes are additional information which we can put in the HTML to
initialize certain DOM properties.
Properties are formed when the browser parses the HTML and generates the DOM. Each of the elements in the DOM have their own set of properties which are all set by the browser. Some of these properties can have their initial value set by HTML attributes. Whenever a DOM property changes which has influence on the rendered page, the page will be immediately re rendered
It is also important to realize that the mapping of these properties is not 1 to 1. In other words, not every attribute which we give on an HTML element will have a similar named DOM property.
Furthermore have different DOM elements different properties. For example, an <input> element has a value property which is not present on a <div> property.
Example:
Let's take the following HTML document:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> <!-- charset is a attribute -->
<meta name="viewport" content="width=device-width"> <!-- name and content are attributes -->
<title>JS Bin</title>
</head>
<body>
<div id="foo" class="bar foobar">hi</div> <!-- id and class are attributes -->
</body>
</html>
Then we inspect the <div>, in the JS console:
console.dir(document.getElementById('foo'));
We see the following DOM properties (chrome devtools, not all properties shown):
We can see that the attribute id in the HTML is now also a id property in the DOM. The id has been initialized by the HTML (although we could change it with javascript).
We can see that the class attribute in the HTML has no corresponding class property (class is reserved keyword in JS). But actually 2 properties, classList and className.
well these are specified by the w3c what is an attribute and what is a property
http://www.w3.org/TR/SVGTiny12/attributeTable.html
but currently attr and prop are not so different and there are almost the same
but they prefer prop for some things
Summary of Preferred Usage
The .prop() method should be used for boolean attributes/properties and for properties which do not exist in html (such as window.location). All other attributes (ones you can see in the html) can and should continue to be manipulated with the .attr() method.
well actually you dont have to change something if you use attr or prop or both, both work
but i saw in my own application that prop worked where atrr didnt so i took in my 1.6 app prop =)
Update to my answer this a citation from https://angular.io/guide/binding-syntax
HTML attributes and DOM properties
Attributes initialize DOM properties and you can configure them to modify an element's behavior, but Properties are features of DOM nodes.
A few HTML attributes have 1:1 mapping to properties; for example, id.
Some HTML attributes don't have corresponding properties; for example, aria-*.
Some DOM properties don't have corresponding attributes; for example, textContent.
Remember that HTML attributes and DOM properties are different things, even when they have the same name.
Example 1: an
When the browser renders , it creates a corresponding DOM node with a value property and initializes that value to "Sarah".
<input type="text" value="Sarah">
When the user enters Sally into the , the DOM element value property becomes Sally. However, if you look at the HTML attribute value using input.getAttribute('value'), you can see that the attribute remains unchanged—it returns "Sarah".
The HTML attribute value specifies the initial value; the DOM value property is the current value.
Example 2: a disabled button
A button's disabled property is false by default so the button is enabled.
When you add the disabled attribute, you are initializing the button's disabled property to true which disables the button.
<button disabled>Test Button</button>
Adding and removing the disabled attribute disables and enables the button. However, the value of the attribute is irrelevant, which is why you cannot enable a button by writing Still Disabled.
To control the state of the button, set the disabled property instead.
Property and attribute comparison
Though you could technically set the [attr.disabled] attribute binding, the values are different in that the property binding must be a boolean value, while its corresponding attribute binding relies on whether the value is null or not. Consider the following:
<input [disabled]="condition ? true : false">
<input [attr.disabled]="condition ? 'disabled' : null">
The first line, which uses the disabled property, uses a boolean value. The second line, which uses the disabled attribute checks for null.
Generally, use property binding over attribute binding as a boolean value is easy to read, the syntax is shorter, and a property is more performant.
Attribute: Attributes are defined by HTML and are used to customize a tag.
Properties: HTML DOM properties are values (of HTML Elements) that you can set or change.
So, the main differences between attributes and properties are:
Attributes are defined by HTML, but properties are defined by the DOM.
The value of an attribute is constant, but the value of a property is variable.
The attribute’s main role is to initializes the DOM properties. So, once the DOM initialization complete, the attributes job is done.
Please take time to read the question in full before assuming that it's a duplicate of .prop() vs .attr()
I've read .prop() vs .attr() and a handful of the duplicates and related non-duplicates. My question is: when is it appropriate to pass values to .attr() when dealing with HTML and the DOM?
Of course the simple answer is "why, whenever you wish to set or modify the value of an attribute - otherwise (and usually) use .prop()."
But what I really want to know is when should you wish to. In the jQuery docs for the method, I see examples of setting things like id, src alt, and title on img elements. But the docs don't seem to give any indication of why you may want to do so, over using .prop() to set these particular attributes.
What I'm after is a guiding principle of when to use .attr() to set things rather than .prop().
Related note: the particular case I'm working on is what's the proper way to change the action on a form, but really I want the perspective and understanding behind the decision.
edit To clarify, I am not looking for:
the differences between properties and attributes
the differences between .attr() and .prop()
the differences between using .attr() and .prop() to get values for either attributes or properties
Otherwise, we could just mark this as a duplicate and call it a day :) No offense intended whatsoever to what's been offered so far - just wanted to make it clear that I'm looking for info on what determines when it's right to use .attr() to set the attribute value, which info I did not find on the venerable .prop() vs .attr() (though if it's there and I missed it, let's definitely mark this as a duplicate!) Thanks!
From http://jq4you.blogspot.in/2013/04/jquery-attr-vs-prop-difference.html:
Jquery attr() vs prop()
jQuery.attr()
Get the value of an attribute for the first element in the set of matched elements.
whereas,
jQuery.prop()
Get the value of a property for the first element in the set of matched elements.
Before jQuery 1.6 , the attr() method sometimes took property values into account when retrieving some attributes, which caused in
inconsistent behavior. And thus, the prop() method was introduced. As
of jQuery 1.6. , the .prop() method provides a way to explicitly
retrieve property values, while .attr() retrieves attributes.
What actually is Attributes?
Attributes carry additional information about an HTML element and come
in name=”value” pairs. You can set an attribute for HTML element and
define it while writing the source code.
simple example can be:
<input id="test" type="test" value="test">
here, "type","value", "id" are attributes of the input elements.
From .prop() vs .attr():
I'll summarize the main issues:
You usually want prop() rather than attr().
In the majority of cases, prop() does what attr() used to do. Replacing calls to attr() with prop() in your code will generally
work.
Properties are generally simpler to deal with than attributes.
An attribute value may only be a string whereas a property can be of any type. For example, the checked property is a Boolean, the
style property is an object with individual properties for each
style, the size property is a number.
Where both a property and an attribute with the same name exists, usually updating one will update the other, but this is not the case
for certain attributes of inputs, such as value and checked: for
these attributes, the property always represents the current state
while the attribute (except in old versions of IE) corresponds to the
default value/checkedness of the input (reflected in the defaultValue
/ defaultChecked property).
This change removes some of the layer of magic jQuery stuck in front of attributes and properties, meaning jQuery developers will
have to learn a bit about the difference between properties and
attributes. This is a good thing.
Jsfiddle try yourself
After lots of reading and re-reading, I think the answer is this. (And rather than try to extract just the part of this that applies to the original question, I think it makes sense to give the full set of 'rules' for context.)
1. Use .attr() only when
getting/setting data-* attributes
working with an attribute/property pair that aren't 1:1 (like href on an anchor element)
2. Use .prop() in all other cases
3. Except for value. Use .val() to get/set an input's value.
Don't use .attr('value')
Don't use .attr('value', 'foo')
Don't use .prop('value')
Don't use .prop('value', 'foo')
I think by following these rules the answer to the question of what happens to properties when you pass a value to .attr() ends up being "who cares?". And the answer of what .attr('foo', 'bar') would be useful for if the now-deprecated use of .attr() to set property values were to be removed ends up being "to set/modify data-* attributes".
If anyone else can think of other cases when using .attr() would be preferable to using .prop() please chime in.
This is my code:
var chk="checked";
document.getElementById("chk").chk=true;
where I used variable to set attribute in the second line.
but this is not working with no error.
Please help me to find this.
You might want:
document.getElementById("chk").setAttribute(chk, true);
which will set it as HTML attribute (not the object property - for that you'd use [] brackets). This is what you're probably looking for because you're operating on an HTMLElememnt.
To clarify:
setAttribute - set's an attribute on an HTML element. It will turn this: <div> into that: <div checked="true"> (assuming the element under question is a div)
[] - use for plain JS objects. In that case the name 'property' is rather used, not 'attribute'
Also note that if the element is <input>, both approaches will work. That's because HTMLInputElement contains the 'checked' attribute. See HTMLInputElement MDN page for details.
Use like this.
document.getElementById("chk").setAttribute(chk, true);
Try this:
document.getElementById("chk")[chk] = true;
This one sets the property
or use the .setAttribute property
document.getElementById("chk").setAttribute(chk, true);
This will set the attribute. If you are using it on HTML elements then this one is a better pick for you as this will set the HTML attribute.
Try,
document.getElementById("chk")[chk] = true;
You can add variables to any JavaScript object which is why the code will run without an error, but -- as you've observed -- it won't have any side effects if the property is not a predefined, semantically meaningful one. For that, you should read some documentation for the given element. For the checkbox element, the name of the property you are looking for is checked. (Note that using the dot syntax treats the text to the right as the name of the property, it does not evaluate it, first. For dynamic evaluation of the property name, use the [] syntax for normal objects and setAttribute for HTML attributes).
chk is a javascript variable in your case. When you getElementById, it refers to the HTML document and the tags in it. Example,
<input id=appleId type="radio" name="fruit" value="Apple" />
In JS, you can then say,
document.getElementById("appleId").checked = true;
Refer to How can I check whether a radio button is selected with JavaScript?
If you removeProp on something you should have used removeAttr() on will it silently fail? Will it work? Will it actually remove the entire attribute or just the value inside it?
If checked is added using removeProp(), can it be removed with removeAttr()?
Many questions!
The official jQuery blog provides a very clear explanation:
In the 1.6 release we’ve split apart
the handling of DOM attributes and DOM
properties into separate methods. The
new .prop() method sets or gets
properties on DOM elements, and
.removeProp() removes properties. In
the past, jQuery has not drawn a clear
line between properties and
attributes. Generally, DOM attributes
represent the state of DOM information
as retrieved from the document, such
as the value attribute in the markup
. DOM
properties represent the dynamic state
of the document; for example if the
user clicks in the input element above
and types def the .prop("value") is
abcdef but the .attr("value") remains
abc.
In most cases, the browser treats the
attribute value as the starting value
for the property, but Boolean
attributes such as checked or disabled
have unusual semantics.
For example, consider the markup
<input type="checkbox" checked>. The
presence of the checked attribute
means that the DOM .checked property
is true, even though the attribute
does not have a value. In the code
above, the checked attribute value is
an empty string (or undefined if no
attribute was specified) but the
checked property value is true.
Before jQuery 1.6, .attr("checked")
returned the Boolean property value
(true) but as of jQuery 1.6 it returns
the actual value of the attribute (an
empty string), which doesn’t change
when the user clicks the checkbox to
change its state.
There are several alternatives for
checking the currently-checked state
of a checkbox. The best and most
performant is to use the DOM property
directly, as in this.checked inside an
event handler when this references the
element that was clicked. In code that
uses jQuery 1.6 or newer, the new
method $(this).prop("checked")
retrieves the same value as
this.checked and is relatively fast.
Finally, the expression
$(this).is(":checked") works for all
versions of jQuery.
An attribute of an element is something like 'class'. Whereas its property would be 'className'.
This is the reason for adding jQuery.prop and jQuery.propHooks into version 1.6, to make it easier working with both.
So if the the property had the same name as the attribute you could use both removeProp or removeAttr.
I asked a similar question on jQuery forum, got this answer:
Yes, attr is meant for html attributes
as they are strictly defined. prop is
for properties. So for instance, say
you have a node elem with class
"something" (raw element not jQuery
object). elem.className is the
property, but is where the
attribute resides. Changing the class
attribute also changes the property
automatically and vise versa.
Currently, attr is jumbled and
confusing because it has tried to the
job of both functions and there are
many bugs because of that. The
introduction of jQuery.fn.prop will
solve several blockers, separate code
as it should have been separated from
the beginning, and give developers
faster functions to do what they
expect them to do. Let me make up a
percentage for a sec and say that from
my experience in the support IRC and
reading other's code, 95% of the use
cases for attr will not have to switch
to prop.
EDIT
It may be best to stick to using either jQuery.attr or jQuery.prop. Theres seems to be some strange behaviour when setting and removing the checked attribute using both.
See here for an example: http://jsfiddle.net/tomgrohl/uTCJF/
There is a bug in 1.6 to do with selected: http://bugs.jquery.com/ticket/9079
Using jQuery 1.6, I was was trying to clone a menu item which had several id attributes, and so I did this:
$('ul.menu').clone().filter('*').removeProp('id').appendTo('.sidebar');
When I inspected the elements in Firebug I had a lot of id="undefined" - not what I wanted. So now I am using removeAttr and it seems to work much better.
$('ul.menu').clone().filter('*').removeAttr('id').appendTo('.sidebar');
So jQuery 1.6 has the new function prop().
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
or in this case do they do the same thing?
And if I do have to switch to using prop(), all the old attr() calls will break if i switch to 1.6?
UPDATE
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>
(see also this fiddle: http://jsfiddle.net/maniator/JpUF2/)
The console logs the getAttribute as a string, and the attr as a string, but the prop as a CSSStyleDeclaration, Why? And how does that affect my coding in the future?
Update 1 November 2012
My original answer applies specifically to jQuery 1.6. My advice remains the same but jQuery 1.6.1 changed things slightly: in the face of the predicted pile of broken websites, the jQuery team reverted attr() to something close to (but not exactly the same as) its old behaviour for Boolean attributes. John Resig also blogged about it. I can see the difficulty they were in but still disagree with his recommendation to prefer attr().
Original answer
If you've only ever used jQuery and not the DOM directly, this could be a confusing change, although it is definitely an improvement conceptually. Not so good for the bazillions of sites using jQuery that will break as a result of this change though.
I'll summarize the main issues:
You usually want prop() rather than attr().
In the majority of cases, prop() does what attr() used to do. Replacing calls to attr() with prop() in your code will generally work.
Properties are generally simpler to deal with than attributes. An attribute value may only be a string whereas a property can be of any type. For example, the checked property is a Boolean, the style property is an object with individual properties for each style, the size property is a number.
Where both a property and an attribute with the same name exists, usually updating one will update the other, but this is not the case for certain attributes of inputs, such as value and checked: for these attributes, the property always represents the current state while the attribute (except in old versions of IE) corresponds to the default value/checkedness of the input (reflected in the defaultValue / defaultChecked property).
This change removes some of the layer of magic jQuery stuck in front of attributes and properties, meaning jQuery developers will have to learn a bit about the difference between properties and attributes. This is a good thing.
If you're a jQuery developer and are confused by this whole business about properties and attributes, you need to take a step back and learn a little about it, since jQuery is no longer trying so hard to shield you from this stuff. For the authoritative but somewhat dry word on the subject, there's the specs: DOM4, HTML DOM, DOM Level 2, DOM Level 3. Mozilla's DOM documentation is valid for most modern browsers and is easier to read than the specs, so you may find their DOM reference helpful. There's a section on element properties.
As an example of how properties are simpler to deal with than attributes, consider a checkbox that is initially checked. Here are two possible pieces of valid HTML to do this:
<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">
So, how do you find out if the checkbox is checked with jQuery? Look on Stack Overflow and you'll commonly find the following suggestions:
if ( $("#cb").attr("checked") === true ) {...}
if ( $("#cb").attr("checked") == "checked" ) {...}
if ( $("#cb").is(":checked") ) {...}
This is actually the simplest thing in the world to do with the checked Boolean property, which has existed and worked flawlessly in every major scriptable browser since 1995:
if (document.getElementById("cb").checked) {...}
The property also makes checking or unchecking the checkbox trivial:
document.getElementById("cb").checked = false
In jQuery 1.6, this unambiguously becomes
$("#cb").prop("checked", false)
The idea of using the checked attribute for scripting a checkbox is unhelpful and unnecessary. The property is what you need.
It's not obvious what the correct way to check or uncheck the checkbox is using the checked attribute
The attribute value reflects the default rather than the current visible state (except in some older versions of IE, thus making things still harder). The attribute tells you nothing about the whether the checkbox on the page is checked. See http://jsfiddle.net/VktA6/49/.
I think Tim said it quite well, but let's step back:
A DOM element is an object, a thing in memory. Like most objects in OOP, it has properties. It also, separately, has a map of the attributes defined on the element (usually coming from the markup that the browser read to create the element). Some of the element's properties get their initial values from attributes with the same or similar names (value gets its initial value from the "value" attribute; href gets its initial value from the "href" attribute, but it's not exactly the same value; className from the "class" attribute). Other properties get their initial values in other ways: For instance, the parentNode property gets its value based on what its parent element is; an element always has a style property, whether it has a "style" attribute or not.
Let's consider this anchor in a page at http://example.com/testing.html:
<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>
Some gratuitous ASCII art (and leaving out a lot of stuff):
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| HTMLAnchorElement |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| href: "http://example.com/foo.html" |
| name: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| attributes: |
| href: "foo.html" |
| name: "fooAnchor" |
| id: "fooAnchor" |
| class: "test one" |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
Note that the properties and attributes are distinct.
Now, although they are distinct, because all of this evolved rather than being designed from the ground up, a number of properties write back to the attribute they derived from if you set them. But not all do, and as you can see from href above, the mapping is not always a straight "pass the value on", sometimes there's interpretation involved.
When I talk about properties being properties of an object, I'm not speaking in the abstract. Here's some non-jQuery code:
var link = document.getElementById('fooAnchor');
alert(link.href); // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"
(Those values are as per most browsers; there's some variation.)
The link object is a real thing, and you can see there's a real distinction between accessing a property on it, and accessing an attribute.
As Tim said, the vast majority of the time, we want to be working with properties. Partially that's because their values (even their names) tend to be more consistent across browsers. We mostly only want to work with attributes when there is no property related to it (custom attributes), or when we know that for that particular attribute, the attribute and the property are not 1:1 (as with href and "href" above).
The standard properties are laid out in the various DOM specs:
DOM2 HTML (largely obsolete, see the HTML spec instead)
DOM2 Core (obsolete)
DOM3 Core (obsolete)
DOM4
These specs have excellent indexes and I recommend keeping links to them handy; I use them all the time.
Custom attributes would include, for instance, any data-xyz attributes you might put on elements to provide meta-data to your code (now that that's valid as of HTML5, as long as you stick to the data- prefix). (Recent versions of jQuery give you access to data-xyz elements via the data function, but that function is not just an accessor for data-xyz attributes [it does both more and less than that]; unless you actually need its features, I'd use the attr function to interact with data-xyz attribute.)
The attr function used to have some convoluted logic around getting what they thought you wanted, rather than literally getting the attribute. It conflated the concepts. Moving to prop and attr was meant to de-conflate them. Briefly in v1.6.0 jQuery went too far in that regard, but functionality was quickly added back to attr to handle the common situations where people use attr when technically they should use prop.
This change has been a long time coming for jQuery. For years, they've been content with a function named attr() that mostly retrieved DOM properties, not the result you'd expect from the name. The segregation of attr() and prop() should help alleviate some of the confusion between HTML attributes and DOM properties. $.fn.prop() grabs the specified DOM property, while $.fn.attr() grabs the specified HTML attribute.
To fully understand how they work, here's an extended explanation on the difference between HTML attributes and DOM properties.:
HTML Attributes
Syntax:
<body onload="foo()">
Purpose:
Allows markup to have data associated with it for events, rendering, and other purposes.
Visualization:
The class attribute is shown here on the body. It's accessible through the following code:
var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");
Attributes are returned in string form and can be inconsistent from browser to browser. However, they can be vital in some situations. As exemplified above, IE 8 Quirks Mode (and below) expects the name of a DOM property in get/set/removeAttribute instead of the attribute name. This is one of many reasons why it's important to know the difference.
DOM Properties
Syntax:
document.body.onload = foo;
Purpose:
Gives access to properties that belong to element nodes. These properties are similar to attributes, but are only accessible through JavaScript. This is an important difference that helps clarify the role of DOM properties. Please note that attributes are completely different from properties, as this event handler assignment is useless and won't receive the event (body doesn't have an onload event, only an onload attribute).
Visualization:
Here, you'll notice a list of properties under the "DOM" tab in Firebug. These are DOM properties. You'll immediately notice quite a few of them, as you'll have used them before without knowing it. Their values are what you'll be receiving through JavaScript.
Documentation
JavaScript: The Definitive Guide by
David Flanagan
HTML Attributes,
Mozilla Dev Center
DOM Element Properties, Mozilla Dev Center
Example
HTML: <textarea id="test" value="foo"></textarea>
JavaScript: alert($('#test').attr('value'));
In earlier versions of jQuery, this returns an empty string. In 1.6, it returns the proper value, foo.
Without having glanced at the new code for either function, I can say with confidence that the confusion has more to do with the difference between HTML attributes and DOM properties, than with the code itself. Hopefully, this cleared some things up for you.
-Matt
A property is in the DOM; an attribute is in the HTML that is parsed into the DOM.
Further detail
If you change an attribute, the change will be reflected in the DOM (sometimes with a different name).
Example: Changing the class attribute of a tag will change the className property of that tag in the DOM (That's because class is already used).
If you have no attribute on a tag, you still have the corresponding DOM property with an empty or a default value.
Example: While your tag has no class attribute, the DOM property className does exist with a empty string value.
edit
If you change the one, the other will be changed by a controller, and vice versa.
This controller is not in jQuery, but in the browser's native code.
It's just the distinction between HTML attributes and DOM objects that causes a confusion. For those that are comfortable acting on the DOM elements native properties such a this.src this.value this.checked etc, .prop is a very warm welcome to the family. For others, it's just an added layer of confusion. Let's clear that up.
The easiest way to see the difference between .attr and .prop is the following example:
<input blah="hello">
$('input').attr('blah'): returns 'hello' as expected. No suprises here.
$('input').prop('blah'): returns undefined -- because it's trying to do [HTMLInputElement].blah -- and no such property on that DOM object exists. It only exists in the scope as an attribute of that element i.e. [HTMLInputElement].getAttribute('blah')
Now we change a few things like so:
$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
$('input').attr('blah'): returns 'apple' eh? Why not "pear" as this was set last on that element. Because the property was changed on the input attribute, not the DOM input element itself -- they basically almost work independently of each other.
$('input').prop('blah'): returns 'pear'
The thing you really need to be careful with is just do not mix the usage of these for the same property throughout your application for the above reason.
See a fiddle demonstrating the difference: http://jsfiddle.net/garreh/uLQXc/
.attr vs .prop:
Round 1: style
<input style="font:arial;"/>
.attr('style') -- returns inline styles for the matched element i.e. "font:arial;"
.prop('style') -- returns an style declaration object i.e. CSSStyleDeclaration
Round 2: value
<input value="hello" type="text"/>
$('input').prop('value', 'i changed the value');
.attr('value') -- returns 'hello' *
.prop('value') -- returns 'i changed the value'
* Note: jQuery for this reason has a .val() method, which internally is equivalent to .prop('value')
TL;DR
Use prop() over attr() in the majority of cases.
A property is the current state of the input element. An attribute is the default value.
A property can contain things of different types. An attribute can only contain strings
Dirty checkedness
This concept provides an example where the difference is observable: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty
Try it out:
click the button. Both checkboxes got checked.
uncheck both checkboxes.
click the button again. Only the prop checkbox got checked. 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>
For some attributes like disabled on button, adding or removing the content attribute disabled="disabled" always toggles the property (called IDL attribute in HTML5) because http://www.w3.org/TR/html5/forms.html#attr-fe-disabled says:
The disabled IDL attribute must reflect the disabled content attribute.
so you might get away with it, although it is ugly since it modifies HTML without need.
For other attributes like checked="checked" on input type="checkbox", things break, because once you click on it, it becomes dirty, and then adding or removing the checked="checked" content attribute does not toggle checkedness anymore.
This is why you should use mostly .prop, as it affects the effective property directly, instead of relying on complex side-effects of modifying the HTML.
All is in the doc:
The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
So use prop!
attributes are in your HTML text document/file (== imagine this is the result of your html markup parsed), whereas
properties are in HTML DOM tree (== basically an actual property of some object in JS sense).
Importantly, many of them are synced (if you update class property, class attribute in html will also be updated; and otherwise). But some attributes may be synced to unexpected properties - eg, attribute checked corresponds to property defaultChecked, so that
manually checking a checkbox will change .prop('checked') value, but will not change .attr('checked') and .prop('defaultChecked') values
setting $('#input').prop('defaultChecked', true) will also change .attr('checked'), but this will not be visible on an element.
Rule of thumb is: .prop() method should be used for boolean attributes/properties and for properties which do not exist in html
(such as window.location). All other attributes (ones you can see in
the html) can and should continue to be manipulated with the .attr()
method. (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/)
And here is a table that shows where .prop() is preferred (even though .attr() can still be used).
Why would you sometimes want to use .prop() instead of .attr() where latter is officially adviced?
.prop() can return any type - string, integer, boolean; while .attr() always returns a string.
.prop() is said to be about 2.5 times faster than .attr().
.attr():
Get the value of an attribute for the first element in the set of matched elements.
Gives you the value of element as it was defined in the html on page load
.prop():
Get the value of a property for the first element in the set of matched elements.
Gives the updated values of elements which is modified via javascript/jquery
Usually you'll want to use properties.
Use attributes only for:
Getting a custom HTML attribute (since it's not synced with a DOM property).
Getting a HTML attribute that doesn't sync with a DOM property, e.g. get the "original value" of a standard HTML attribute, like <input value="abc">.
attributes -> HTML
properties -> DOM
Before jQuery 1.6 , the attr() method sometimes took property values into account when retrieving attributes, this caused rather inconsistent behavior.
The introduction of the prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
The Docs:
jQuery.attr()
Get the value of an attribute for the first element in the set of matched elements.
jQuery.prop()
Get the value of a property for the first element in the set of matched elements.
One thing .attr() can do that .prop() can't: affect CSS selectors
Here's an issue I didn't see in the other answers.
CSS selector [name=value]
will respond to .attr('name', 'value')
but not always to .prop('name', 'value')
.prop() affects only a few attribute-selectors
input[name] (thanks #TimDown)
.attr() affects all attribute-selectors
input[value]
input[naame]
span[name]
input[data-custom-attribute] (neither will .data('custom-attribute') affect this selector)
Gently reminder about using prop(), example:
if ($("#checkbox1").prop('checked')) {
isDelete = 1;
} else {
isDelete = 0;
}
The function above is used to check if checkbox1 is checked or not, if checked: return 1; if not: return 0. Function prop() used here as a GET function.
if ($("#checkbox1").prop('checked', true)) {
isDelete = 1;
} else {
isDelete = 0;
}
The function above is used to set checkbox1 to be checked and ALWAYS return 1. Now function prop() used as a SET function.
Don't mess up.
P/S: When I'm checking Image src property. If the src is empty, prop return the current URL of the page (wrong), and attr return empty string (right).
1) A property is in the DOM; an attribute is in the HTML that is
parsed into the DOM.
2) $( elem ).attr( "checked" ) (1.6.1+) "checked" (String) Will
change with checkbox state
3) $( elem ).attr( "checked" ) (pre-1.6) true (Boolean) Changed
with checkbox state
Mostly we want to use for DOM object rather then custom attribute
like data-img, data-xyz.
Also some of difference when accessing checkbox value and href
with attr() and prop() as thing change with DOM output with
prop() as full link from origin and Boolean value for checkbox
(pre-1.6)
We can only access DOM elements with prop other then it gives undefined
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>prop demo</title>
<style>
p {
margin: 20px 0 0;
}
b {
color: blue;
}
</style>
</head>
<body>
<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>
<script>
$("input").change(function() {
var $input = $(this);
$("p").html(
".attr( \"checked\" ): <b>" + $input.attr("checked") + "</b><br>" +
".prop( \"checked\" ): <b>" + $input.prop("checked") + "</b><br>" +
".is( \":checked\" ): <b>" + $input.is(":checked")) + "</b>";
}).change();
</script>
</body>
</html>
There are few more considerations in prop() vs attr():
selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, and defaultSelected..etc should be retrieved and set with the .prop() method. These do not have corresponding attributes and are only properties.
For input type checkbox
.attr('checked') //returns checked
.prop('checked') //returns true
.is(':checked') //returns true
prop method returns Boolean value for checked, selected, disabled,
readOnly..etc while attr returns defined string. So, you can directly
use .prop(‘checked’) in if condition.
.attr() calls .prop() internally so .attr() method will be slightly
slower than accessing them directly through .prop().
Gary Hole answer is very relevant to solve the problem if the code is written in such way
obj.prop("style","border:1px red solid;")
Since the prop function return CSSStyleDeclaration object, above code will not working properly in some browser(tested with IE8 with Chrome Frame Plugin in my case).
Thus changing it into following code
obj.prop("style").cssText = "border:1px red solid;"
solved the problem.