Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

What are the differences between .prop(), .attr(), and .val()?

I’m trying to wrap my head around the differences between these jQuery methods

.val()

.prop()

.attr()

All of them seem to be about getting the value of something. But I can’t quite figure out which ones I’m supposed to use in most circumstances. The problem might be that I don’t quite get the difference between attributes and properties. To get a better sense of the difference, I’ve read multiple things, including this blog post:

http://jquery-howto.blogspot.com/2011/06/html-difference-between-attribute-and.html

This is what I got out of reading that particular post:

+Both have to do with giving value to, em, “things” in the HTML

+Attributes do not change and are found in the HTML doc

+Properties do change and are found in the DOM. They are representations of attributes, whatever that means. (And not too sure what the DOM is. In my head, it’s a “tree” found inside the browser’s console, lol.)

Despite this “understanding”, I still can’t keep track of these methods, and often use .attr() when I should use .prop() . . . and then there’s also .val(), which seems to do the job of both, except that it doesn’t.

Yike. As you can see, I am very confused.

Here's an example. It comes from the jQuery Basics exercises—“Creating a Mobile Drop Down Menu.” The code creates a drop-down that holds the same list items that are in the menu. You’ll see that the code uses all three of the methods I’m having trouble with

var $select = $("<select></select>");

$("body").append($select);

$("#menu a").each( function (){
  var $anchor = $(this);
  var $option = $("<option></option>");
    if ($anchor.parent().hasClass("selected")) {
      $option.prop("selected", true);
    }
  $option.val($anchor.attr("href"));
  $option.text($anchor.text());
  $select.append($option);   
});

$select.change( function (){
window.location = $select.val();
})

I've been playing around with the code, inserting .prop() in place of .val() or .attr() instead of .prop() to purposefully make the code break. For instance, if I change

$option.val($anchor.attr("href")); 

to

$option.prop($anchor.attr("href"));

the code doesn’t seem to break, but if I click on one of the options in the drop-down list, I go to a page that says the URL is not found. I don’t really understand why this happens. What is it about the .val() method that makes it work? Why not use .val() all the time?

Trying to sort out the different use cases on my own isn’t quite working. Yuuuuge thanks to anyone who can help me!

--Rose

1 Answer

Let's try an example:

<form>
  <select>
    <option value="option1">Red</option>
    <option value="option2">Blue</option>
  </select>
  <input type="checkbox" name="check" checked> I agree
</form>

In the HTML above you could use .val() on the option elements to retrieve "option1" and "option2". You might also be able to use .attr("value") to retrieve those values, since "value" is the attribute name. You could use .prop("checked") to see if the checkbox is checked. jQuery treats attributes without "values" as simple properties - this is from their documentation:

"To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method."

In your code it's no surprise it goes to a "page not found", since this line

window.location = $select.val();

is looking for the value of the element, but in your code you set the prop instead:

$option.prop($anchor.attr("href"));

I hope I didn't make your confusion worse!

One more example:

<input type="text" value="John" name="first-name" disabled>

Here name is an attribute, "John" is the value, and disabled is a property.

Wow, your examples and explanations make a lot of sense. I will probably fumble around a bit more, but I think I'm starting to see the light.

Thank you for helping me! (and twice in one day, too!!)

I have another question for you, if you don't mind.

The following is a code snippet from the jQuery Basics "lightbox" challenge. I put .prop() into all the places that .attr() appears, and the code still ran. Any thoughts as to why?

var $overlay = $("<div id='overlay'></div>");
var $image = $("<img>");
var $caption = $("<p></p>");

$overlay.append($image);
$overlay.append($caption);
$("body").append($overlay);

$("#imageGallery a").click( function(event){
  event.preventDefault();
  var $imageLocation = $(this).attr("href");
  var $imageCaption = $(this).children().attr("alt");
  $image.attr("src", $imageLocation);
  $caption.text($imageCaption);
  $overlay.show();  
})

$overlay.click( function(){
  $overlay.hide();
})

I wish I could give you a "definitive" answer - the jQuery documentation is pretty murky. The accepted answer in this Stack Overflow thread is very informative though: http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html Basically it seems like all attributes reflect properties, but not all properties are HTML attributes.

Hey, that Stack Overflow explanation was very helpful! I think I'm starting to get a feel for the differences. Thank you for your help, David!