In the following code, why is it necessary to surround 'this' with the $ function?
var x = $('div');
x.click(function(){
$(this).hide();
});
doesn't 'this' just refer to the expression x which is itself a jQuery object?
The value of this will be the DOM node representing the clicked element. $(this) will be a jQuery object wrapping that DOM node, and providing extra functions like .show(), .append(), etc.
No : this is the unwrapped DOM element, as specified in the documentation :
The handler parameter takes a callback function, as shown above.
Within the handler, the keyword this refers to the DOM element to
which the handler is bound. To make use of the element in jQuery, it
can be passed to the normal $() function.
this reffers div ... thats mean that your div will hide when you click in it.
this always reffers what its in context.
Related
At some place I have a code elem.addEventListener(event, listener, false);
The above code works for
this.buttonBar = doc.getElementsByClassName("wmd-button-bar" + postfix)[0]
But when I change to
this.buttonBar = $('.wmd-button-bar').first();
It does not work. In whole html code I have only one wmd-button-bar class.
The reason why it's not working is because $('.wmd-button-bar').first(); (which equals to $('.wmd-button-bar').eq(0)) returns the first jQuery wrapped instance.
Therefore you should use jQuery's own API for adding the listener.
However, if you want to receive a first DOM element from collection, you should use
$('.wmd-button-bar').get(0);
This will return first element from the jQuery wrapped collection as a DOM element.
I have a function that creates a div with two buttons and returns the ids of the wrapper and the buttons. When I use .text() to find the text of the button it works fine, but when i use .text() within the on method it gives me a TypeError.
function generateTwoBtns(answerSpace, btnOneName, btnTwoName) {
const btnHTML =
`
<div id="twoBtnWrapper">
<button id="btnOne">${btnOneName}</button>
<button id="btnTwo">${btnTwoName}</button>
</div>
`
$(answerSpace).html(btnHTML)
return {
wrapper: '#twoBtnWrapper',
btnOne: '#btnOne',
btnTwo: '#btnTwo'
}
}
//Works
console.log($(buttons.btnOne).text())
//Doesn't work
$(buttons.btnOne).on('click', function() {
console.log(this.text())
})
I've looked at the answer found here: Uncaught TypeError: $this.text is not a function. This is the same sort of problem I'm having. but in my code i can't see why this.text() works fine outside the on method, but doesn't work within it.
.text() is a jQuery method, meant to be used on jQuery objects. In your event handler, this refers to a standard DOM element which does not have a text method, hence your error (.text is not a function that a DOM element has).
It works here:
console.log($(buttons.btnOne).text())
Because you are wrapping the DOM element(s) that match the buttons.btnOne selector in a jQuery object and then calling .text() on that.
Change the code to:
$(this).text()
So that the DOM "button" element that got clicked gets wrapped in a jQuery object and then it will work.
That is because this actually refer to the DOM element, and the DOM element does not have a .text() method. What you want is to use it on a jQuery object, i.e.: $(this) instead:
$(buttons.btnOne).on('click', function() {
console.log($(this).text())
});
From the official jQuery documentation, they describe what this actually stands for in the context of a callback (emphasis my own):
When jQuery calls a handler, the this keyword is a reference to the element where the event is being delivered; for directly bound events this is the element where the event was attached and for delegated events this is an element matching selector. (Note that this may not be equal to event.target if the event has bubbled from a descendant element.) To create a jQuery object from the element so that it can be used with jQuery methods, use $( this ).
I'm learning JavaScript and JQuery, and trying to wrap my head around "this." Is
$("p").click(function(){ $("p").slideUp('slow');});
functionally, the same as
$("p").click(function(){ $(this).slideUp('slow');});
?
I'm sure there are more clever ways to use "this", but if I'm right that it is functionally the same, then I know I have a little bit better understanding.
"this" in javascript refers to the context of a function call. The value of "this" depends on how the caller invoked the method. In the case of jQuery, when it invokes an event handler, it sets "this" to the DOM element that is the target of the event.
$(this) wraps this DOM element in a jQuery object so that you can use jQuery methods against it.
$("p") selects all paragraph elements in your DOM.
$(this) selects only the element that was the target of the click event.
$("p").slideUp() will affect all paragraph elements on the page.
$(this).slideUp() will only affect a single element that was the target of the click event.
I have the following code:
<script type="text/javascript">
$("*").click(function(event){
var x = event.target;
if (x.nodeName == "DIV"){
alert(x.attr("class"));
}
})
</script>
This throws an 'undefined' exception... Is there any other way to get the class of an element which triggered the 'click' event? Thank you in advance!
event.target is a DOM object. So to use jQuery methods you have to convert it to jQuery object:
alert($(x).attr("class"));
Otherwise, you may use property className to get the class of the element:
alert(x.className);
BTW, in your example you may simply use this keyword instead of event.target.
jQuery offers some syntactic sugar to help with your check - .is() allows you to validate an element against any other valid selector:
var $target = event.target;
if ($target.is('div')){
alert($target.attr('class'));
}
There are some further changes to consider:
.click(handler) is explicitly assigned to the matching elements (every single element in your case). This adds overhead; also the handler will not apply to any element added dynamically after the handler assignment is executed. Instead, delegate the handler by using on()
refactor your logic so that instead of handling every single click and validating it you could make it applicable only to divs in the first place by changing the selector to $('div')
rely on this which is pretty much the convention
After all these changes the code becomes smaller and more readable:
$('div').on('click', function() {
alert($(this).attr('class'));
});
i made a fiddle with buttons. Now in the javascript, I'm trying to learn jquery and by doing so I'm converting old fiddles into jquery from javascript however I know how.
My problem is that in my function called init, I can't figure out how to convert the javascript way of get an html element with an id stored in a variable.
Old code in javascript:
var but = document.getElementById("but");
New code in jQuery:
var but = $('#but');
I think the problem is that I start with a javascript statement but then use jQuery. I don't know what to do in terms of variables in jQuery.
You need to add in [0] to your jquery code to get the document element, but that is rather pointless with the jquery method of adding event listeners. I would suggest either $('#but').mouseout(etc) or $('#but').on('mouseout', etc).
I've updated your jsfiddle to work as expected, though I'll attempt to give a short tut here:
There are two methods of adding event listeners you should familiarize yourself with per the jquery documentation; the .on() method, and the .(event)() method. The latter you can add to jquery ojects in lieu of object.(eventName)() as an example, adding the click handler to an object: object.click(function() { console.log('executed'); });
This method however is not 'live' it will not update itself if the elements are added dynamically, and the events are only attached when the document is ready($(document).ready(function() { do stuff });). In order to attach events to dynamically added elements, we need the .on() method.
Take for example the following html:
<div class="wrapper">
<span class="dynamically_added">stuff</span>
</div>
In order to attach an event listener to the dynamically added span, in your jquery, add the following:
$(".wrapper").on('click', '.dynamically_added', function() {
console.log('executed');
});
The first parameter of .on() is(are) the event(s). You can attach multiple events by delimiting them with spaces: .on('click hover'). The second parameter is either the function to execute, or the targeted element. In the case of the above example it is the span. The last parameter is of course the function to execute. As far as I am aware, you need to have an anonymous function to refer to the function to execute, instead of simply writing it there.
I hope this has helped.
$('#but') returns a jQuery object, not a DOM object. You can either call jQuery methods on that or you can get the DOM object out of it, but you can't use DOM methods directly on it. If you want the DOM object out of it, you can get it with:
$('#but')[0]
And, your method would be this:
function init() {
var but = $('#but')[0];
but.addEventListener("mouseover", butResult, false);
but.addEventListener("mouseout", reverse, false);
var button = $('#button')[0];
button.addEventListener("mouseover", buttonResult, false);
button.addEventListener("mouseout", reverse, false);
}
Or, instead of using native DOM methods, you can use jQuery methods on the jQuery object.
function init() {
$('#but').on("mouseover", butResult).on("mouseout", reverse);
$('#button').on("mouseover", buttonResult).on("mouseout", reverse);
}
Not sure if I understand you ? completely, but, is this what you're roughly looking for:
var b1 = document.getElementById('button');
var b2 = $(b1);
b2.click( function(){
alert('hi');
})