Introduction: Why is this topic so important?
\nIf you've ever written jQuery code that needed to get or set an attribute value of an HTML element, you've undoubtedly encountered two methods: .prop() and .attr(). At first glance, they do the same thing. But in practice, the difference between them is a source of hundreds of bugs and thousands of questions on Stack Overflow.
In this step-by-step tutorial, we will once and for all figure out how .prop() and .attr() differ in jQuery, when to use which, and how to avoid the trap. We will write live code, look at real browser behavior, and remember a simple rule.
This article is not dry documentation. It is your personal guide to one of the most confusing topics in jQuery.
\n\nIn Short: Attributes vs Properties
\nBefore diving into the code, let's understand the theory. In the DOM (Document Object Model), there are two concepts:
\n- \n
- Attribute — what is written in the HTML code. For example,
<input type="checkbox" checked="checked">. Attributes are always strings. \n - Property — what is stored in the DOM element object after the browser has parsed the HTML. Properties can be of any data type: string, boolean, number, object. \n
The .attr() method works with attributes. The .prop() method works with properties. Sounds simple? Yes, but there are nuances.
The Main Trap: Boolean Attributes
\nThe most popular example that confuses beginners is checkboxes, radio buttons, and other elements with boolean attributes (checked, disabled, selected, readonly).
Imagine you have this HTML:
\n<input type="checkbox" id="myCheckbox" checked>\nYou want to check if the checkbox is ticked. It's logical to write this:
\nconsole.log( $('#myCheckbox').attr('checked') ); // "checked" (string!)\nconsole.log( $('#myCheckbox').prop('checked') ); // true (boolean!)\nThere it is, the difference! .attr() returns the string "checked" if the attribute is present in the HTML, and undefined if it is not. Meanwhile, .prop() returns true or false, depending on the current state of the element in the DOM.
Now for the interesting part: what happens if the user unchecks the box?
\n// After the user has unchecked the box:\nconsole.log( $('#myCheckbox').attr('checked') ); // "checked"! (HTML hasn't changed)\nconsole.log( $('#myCheckbox').prop('checked') ); // false (state has changed)\nThis is why using .attr() to check the state of a checkbox is a mistake. The checked attribute in the HTML remains unchanged, while the checked property in the DOM changes dynamically. .prop() always gives the correct answer.
The Rule of Thumb
\nThere is a simple rule to help you avoid mistakes:
\n- \n
- Use
.prop()when you need to get or change the dynamic state of an element (e.g.,checked,disabled,selected,valueof an input). \n - Use
.attr()when you need to read or change a static attribute from the HTML (e.g.,href,src,data-*,id,class). \n
Remember: .prop() is for properties that change during operation. .attr() is for attributes defined in the markup.
Step-by-Step Example: Working with disabled
\nLet's break down another classic case — a button with the disabled attribute.
<button id="myButton" disabled>Click me</butto