What is the difference between $(this) and this - javascript

I have the following code
$('a').click(function() {
var url= this.href;
alert(url);
});
This works just fine and sure enough the returned result is the url of a tag.
However if I change the above code to
$('a').click(function() {
var url= $(this).href;
alert(url);
});
The result is undefined.
Anyone please help to clear this out for me? I am banging my head for this ....

$(this) creates a jQuery object which wraps this. The native DOM object has an href attribute, but jQuery does not.
$(this).attr("href") would work.

this in your case is the actual dom element, so the anchor tag
$(this) is a jquery object that wraps that dom element with all the jquery goodness.
so .href is not an attribute of that jquery object, but it is of the dom object.
you could use $(this).attr('href') to achieve the same thing using the jQuery object.

This is because you're using a javascript DOMElement in the first example and a jQuery Object in the second example. The jQuery Object wraps around the DOMElement and provides you a lot of features.
You can access the url as follow:
$('a').click(function() { var url= $(this).attr('href'); alert(url); });

The difference is between a DOM element and a jQuery selection.
"this" in the code you've given above is a reference to the link's DOM element. $(this) creates a jQuery selection based upon the DOM element that contains only that link.
The jQuery selection will give you different features at the cost of a little performance. Your link element has a href property (i.e. one you can access through this.href) whereas the jQuery selection has all the normal jQuery properties & methods.
For getting the link target, this.href is definitely the way to go. It is simpler, faster and less verbose.

Lots of good answers, just wanted to add that you could also do this:
$('a').click(function(e) {
alert($(this)[0].href);
});

Related

JQuery keyword "this" does not get attribute value

I am playing around with the JQuery keyword this.
I have come across something I do not understand.
Here is my code:
<body>
<a id="link_1">jQuery.com</a>
<!-- adding JQUERY -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<!-- my JavaScript -->
<script>
$("a").attr("href", "target_1");
$("a").attr("new_attribute", "new_attribute_value");
$(function ($) {
$("a").mouseenter(function(){
alert(this.id);
alert(this.href);
alert(this.new_attribute);
});
});
</script>
</body>
I want JQuery to return the id, href and my new_attribute as an alert message.
I can call the id on the keyword 'this' (with this.id) and it works as expected.
I can also call the href on the keyword this (with this.href) and it works as expected (even though I set the value of href with JQuery only (an not inline)).
However with the new attribute "new_attribute" this kind of set & get does not work as expected.
my question: What am I doing wrong? Is it only possible to call 'certain /limited' attributes on the keyword 'this'.
It's because new_attribute is not a valid attribute.
Some built in attributes are mapped to properties, and when you do
this.id
you're really getting the id property, not the attribute, as that would be
this.getAttribute('id')
you could do
this.getAttribute('new_attribute')
but you should really be using data-* attributes, and not make up your own, but jQuery's data() maps data internally and doesn't add attributes, but in your case that's probably what you want, just store arbitrary data on the element
$("a").attr("href", "target_1");
$("a").data("new_attribute", "new_attribute_value");
$(function ($) {
$("a").mouseenter(function(){
alert(this.id);
alert(this.href);
alert( $(this).data('new_attribute') );
});
});
In this context this points to HTMLAnchorElement object, and the problem here is the difference between HTMLElement attributes and their properties. Simply saying, attributes are rendered as a part of HTML, and used for additional object declarative configuration from the side of HTML markup.
On the other hand, there are properties of the object, which not always have corresponding attributes. Sometimes they do, but in most cases - they don't.
You can set any arbitrary attribute to HTMLElement like you did with new_attribute, but this custom attribute value will not become an object property. So reading such custom attribute as property will yield undefined.
"this" refers to the DOM element (try console.log(this)). An Element exposes its id attribute, as you can see here : https://developer.mozilla.org/en-US/docs/Web/API/element
Since it is an A element, it also exposes its href attribute. But it never knows your custom attribute. So it can't expose it.
Try this in you event handler :
var $this = $(this);
alert($this.attr('new_attribute'));
You need to treat this as a selector, so write it like $(this)
Your problem is that you set an attribute with the attr() method but you're querying (getting) it with a call to an equivalent method to jQuery'sprop().
Since this is a non standard attribute, the main interface for the anchor <a> element HTMLAnchorElement or other interfaces that it inherits from in the DOM don't have/implement a new_attribute property in place, your this.new_attribute would always return undefined.
However, if you'd like to keep experimenting with the this keyword, you could try something along these lines this.attributes['new_attribute']and you won't have any unpleasant surprises in your coding excursion anymore :)

Get a jQuery element for a DOMElement

I know how to do the opposite. Getting a certain DOMElement for a jQuery element is easy. (Use the get() method)
But how can you get a jQuery element for a specific DOMElement?
Unfortunately this DOMElement does not have any attributes like class or id so constructing a selector is not really an option.
Lets say I have this html:
<div class="edit">Abcd<b><i><u>asdasd</u>adasda</i></b>sdfsdf<br>asd</div>
I am in the u-DomElement. How can I get this as a jQuery element?
Is there a smart way to do this?
EDIT:
I wanted to know if there is a gerneral way to do this. Not specific to the code shown above.
Like:
DomElement.toJQuery()
Is there anything like that? I am aware that this might not be possible.
Getting a jQuery object for a DOM object is as simple as jQuery(dom_node) (or $(dom_node)). See http://api.jquery.com/jQuery/
This is commonly used in event handlers, which are given the DOM node as this, so that you will often see $(this)
If you want to get just the Element use the below code. if you wanted to get the HTML of any element you might want to add the .html() tag to either of the examples
var myVar = $('.edit u');
or
var myVar = $(".edit").find("u");
Are you looking for this?
$(".edit").find("u");
hope this is what you are looking for,
$(DomElement)
you want a only 1 specific dom element i suggest you find a way to add an id to that element.
but to get an u element inside a edit class:
$('.edit u');
$('.edit').find('u');

How "this" works in jQuery

Can somebody please explain how "this" works in jQuery. I tried to find some information on the net, but because "this" is used a lot in his usual meaning I couldnt find anything good.
I would like to be able to change the background of a list element (<li>) onclick without giving each list element an id.
$('li').on('click.namespace', function() {
console.log(this); /* this is a reference to the DOM
element you clicked */
console.log($(this)); /* this is a jQuery reference to the
DOM element you clicked */
/* using jQuery reference you can change the background in this way */
$(this).css('background-image', 'url(...)');
});
$("li").click(function() {
$(this).css("background-color", "red");
});
Here is an example. $(this) refers to the JQuery object, this refers to the regular DOM object that was clicked on.
Did you find the click() documentation? It shows how you should use the click handlers and it has examples that even use $(this).
Here's an example:
$('li').click(function() {
$(this).attr("class", "clicked");
});
When one clicks on an item, this takes the value of the item being clicked on, that is the DOM element. $(this) gives you access to the jquery API.
If you set the onclick event on the li you can use $(this) to get the jquery object of the li, and then add a class eg. $(this).addClass("newBackground").
jQuery is kind enough to set the context of your function to the thing you're interesting in. In this case the <li> in question. But this is still a naked DOM element, you need to wrap it with $() to use jQuery methods on it.
$('li').on('click', function() {
$(this).css({background:'red'});
});
Sometimes you have to use a bound function (see jQuery.proxy()) as an event handler, in these cases you can access the current element differently, instead of this, you can use the event.currentTarget property, see http://api.jquery.com/event.currentTarget/

jquery append() doesn't preserve data or click handlers

I am trying to append some links with data and a click handler to a containing div.
jQuery 1.4.3
Fails in FireFox 5.0/Chrome 13.0.782, but works in IE9
I first create the element as a jQuery object, then add the data and click handler. Then I use .append() to append it to the container:
var $selector = $('Test');
$selector.data('testdata', "Test");
$selector.click(function(event) {
alert('Clicked: ' + $(this).data('testdata'));
return false;
});
$('#container').append($selector);
I see the link added, but when I click on it, the click handler does not fire.
I thought that maybe I needed to do the append first and then add data+click, but that doesn't work either:
var $selector = $('Test');
$('#container').append($selector);
$selector.data('testdata', "Test");
$selector.click(function(event) {
alert('Clicked: ' + $(this).data('testdata'));
return false;
});
Does append not preserve data and handlers? It seems that when I .append($selector), $selector and the newly added DOM object are not one in the same.
Which browser are you using? Also, which version of JQuery? This works for me in firefox, ie, and chrome on JQuery version 1.6. Here's the test fiddle I was using.
I don't think the append is the cause of your problem. It's because the html you're passing into $() to create your elements is not a simple tag.
According to the documentation of jQuery(html):
If the HTML is more complex than a single tag without attributes, as it is in the above example, the actual creation of the elements is handled by the browser's innerHTML mechanism. In most cases, jQuery creates a new element and sets the innerHTML property of the element to the HTML snippet that was passed in. When the parameter has a single tag, such as $('<img />') or $('<a></a>'), jQuery creates the element using the native JavaScript createElement() function.
This quote is from this page: http://api.jquery.com/jQuery/#jQuery2
This means that you may get a different element than what you intend because it's dependent on the browser's innerHTML property. You may find it easier if you pass in a simple tag '<a></a>' and add other attributes to it as a second argument map to $(html, props).
To get this to work with a simple tag in the $(html, props) call, you would do something like this:
var $selector = $('<a></a>',
{
"class" : "x",
"href" : "#",
text : "Test",
click: function() {
alert('Clicked: ' + $(this).data('testdata'));
return false;
}
});
$('#container').append($selector);
$selector.data('testdata', "Test data");
For my page, the problem exists using jQuery 1.4.3 and 1.4.4. But if I upgrade to 1.6.1, the problem goes away and the code works as expected. At this particular point, I am worried about upgrading to 1.6.1.
My other option is to append the element, then requery for it using jquery before adding data and handlers. That code does work, but obviously not ideal.
I ran into the same issue, try using .appendTo() instead of .append().
It worked for me.

accessing href attribute with classname

I want to access the href attribute with jquery using the class name. How can I do that below is the code.
Hyper Link
I only want to access it with the class-name since I have many links and want to use the classname to access the href link.
Thanks
$('a.class-name').each(function(){
this.href //do something with href
})
Presuming (1) that you are using jQuery 1.6 and (2) that your link is the only one that has that class:
var linkHref = $('a.class-name').prop('href');
If you are using jQuery 1.5 or older, you'll have to use attr rather than prop. If you have more than one element with the class, you'll have to find some other way of identifying which element you want.
Depends what you want - but the href of your link should probably be made into an absolute rather than relative link...
$('a.class-name').each(function(){
alert( this.href ) // alerts http://currentdomain.com/www.google.com
alert( $(this).attr('href') ) // alerts www.google.com
})
To make the element look up faster I'd suggest dropping the tag prefix since you mentioned you have a lot of links.
$('.class-name').prop('href');

Categories

Resources