I'm trying to access 'this' inside a method that is called from a button press, where this refers to both the class and the button pressed:
p.myVar = 'banana';
$('.go').on('click', this._init);
p._init = function(e){
//get the button pressed
//get this.myVar
};
To do this I bind this:
$('.go').on('click', this._init.bind(this));
The above works and I can now access my var via:
this.myVar; //banana
But I can no longer access the button.
How can I access it, use e.currentTarget or is there a better way?
You should use the data argument :
$('.go').on('click', {myVar:'banana'}, this._init);
p._init = function(e){
// use e.data.myVar;
// this is the right matching clicked element
};
I presume your declaring the event listener in a closure, if so you can use a local variable and pass it that, the reference is unique to the closure and can be accessed by the function in the listener when it is called. It becomes a kind of invisible global, the reference only exists to that specific call and the listener function but is still shared.
function initButtons(){
var selfRef = this;
$('.go').on('click',selfRef._init);
}
Related
To initiate the onclick event, I have this
[].forEach.call(btnAddVendorDropDown, (btnAddVendorDropDown) => {
btnAddVendorDropDown.addEventListener('click', onAddVendorDropDownClick, false);
});
The function is
function onAddVendorDropDownClick(e) {
e.preventDefault();
addNewClass(modal, 'is-active');
addNewClass(modalAddVendorDropDown, 'is-active');
const test = $(this).attr('id');
console.log(test);
return test;
}
So what I'm trying to do is when a user clicks btnAddVendorDropDown, the function onAddVendorDropDownClick is called. I need to grab the id from the element. When I do console.log of the element attribute id from inside the function, I get exactly what I need. The problem I'm running into is when I try to grab it from outside the function, I keep getting undefined. I don't understand how I can grab the id once it calls this function from outside this function.
I tried this
var num = onAddVendorDropDownClick();
console.log("the function return is " + num);
Which is what shows undefined.
this is related directly to the caller's scope. This means that without "binding" a scope to your event handler, this is going to refer to your main application scope, and not the scope that jquery passes as you chain functions.
You can either wrap the event object's target:
function onClickHandler(e) {
$(e.target).attr('id');
}
Or you can use $(this) within the jquery context of a click handler:
$('#my-button').on('click', function(e) {
$(this).attr('id');
});
The last example works because it is occurring inside a JQuery closure, so it retains the scope from the previous function. Outside of a closure, this means something else.
$(this) is JQuery context, and you are inside javascript function. You can change the click button to JQuery to use it:
var test;
$("button").click(function(){
test = $(this).attr('id');
console.log(test);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="btnTeste">
Teste
</button>
I'm trying to create a custom module. I'm using prototype to add additional methods. The module will have an event, in which I will have to access a method from the module with 'this'. I will do that using bind.
I ran into a slight problem. I created a method, then using prototype, I assigned the method to a variable with the bind method. The problem is, 'this' isn't the one I passed through bind. Here's the sample code:
JSFiddle
function MyPlugin() {
this.hello = 'hello'
document.addEventListener('click', this.clickedBinded);
this.clickedBinded('e');
}
MyPlugin.prototype.clickedBinded = clicked.bind(this);
function clicked(e) {
console.log(this.hello, e);
}
var plugin1 = new MyPlugin();
How can I get clickedBinded have this as this? Meaning, I don't want this to be Window, I want it to be MyPlugin.
Update
The reason why I did: MyPlugin.prototype.clickedBinded = clicked.bind(this) and not: document.addEventListener('click', this.clicked.bind(this));, is because I'm going to have to remove the event at some point. And as this answer sais, if you're using bind in an event handler, and you want to remove the event, you have to assign the method with bind to a variable.
.bind() has to be called AFTER the object you want it to be bound to has already been created and when you're in the right context to have a reference to the desired object. You are calling .bind() when your code is first loaded. That will not have a meaningful value for this. Instead, change your code to this:
function MyPlugin() {
this.hello = 'hello';
// save bound function so you can use it to remove the listener later
this.fn = this.clicked.bind(this);
document.addEventListener('click', this.fn);
this.clicked('e');
}
MyPlugin.prototype.clicked = function(e) {
console.log(this.hello, e);
}
// method that will remove the event listener
MyPlugin.prototype.stopClick = function() {
document.removeEventListener('click', this.fn);
}
var plugin1 = new MyPlugin();
Notice in this fixed version that .bind(this) is called ONLY when we already have this that corresponds to our current object.
In your version, you were calling clicked.bind(this) when your code was first loaded and this would have a global value which in strict mode would be undefined and in non-strict mode in the browser would be window. The object that you will create with new MyPlugin() doesn't even exist yet when you were calling clicked.bind(this) so there's obviously no way that this could contain the appropriate value.
If you want to be able to remove the event listener later, then just store the bound listener so you can use it later.
As jfriend00 explained, you should bind the event listener inside the constructor. Each instance will have a different listener.
If you want to be able to remove the listener, store it in the instance:
var click = document.getElementById('click'),
remove = document.getElementById('remove');
function MyPlugin() {
this.hello = 'hello';
var listener = clicked.bind(this);
click.addEventListener('click', listener);
remove.addEventListener('click', function self() {
click.removeEventListener('click', listener);
remove.removeEventListener('click', self);
});
}
function clicked(event) {
console.log(this.hello);
}
var plugin1 = new MyPlugin();
<input type="button" id="click" value="Click me" />
<input type="button" id="remove" value="Remove listener" />
Inside an event listener, I need a reference to the element that was the event source. How do I get that?
This should be a no-brainer for anyone doing JavaScript for some time.
All the functions including the event handler are in global scope, and therefore, implicitly made a part of the DOM window object.
function WireHandlers() {
$('.updateResourceImageButton').click(UpdateResourceLinkClickedHandler);
}
function UpdateResourceLinkClickedHandler() {
// I would like a reference to the hyperlink/anchor
// that was actually clicked, i.e. the hyperlink that
// was the source of this event
// would the keyword 'this' evaluate to the element I need?
// or will it evaluate to the HTML DOM 'window' object
// in this context?
}
$(document).ready(function () { WireHandlers(); });
When you pass the function by reference you still get access to the parameters as normal. As such event.target or this will be the clicked element within the UpdateResourceLinkClickedHandler function:
function UpdateResourceLinkClickedHandler(e) {
// clicked element as a native DOM element
var foo = e.target;
var bar = this;
// jQuery object containing clicked element
var $foo = $(this);
}
Note, both foo and bar in this example will contain the same value.
I think you can do it like this
$(this)
also this is from jquery documentation
var target = $( event.target );
as in this page http://api.jquery.com/event.target/ and look at this article for more information http://www.pkshiu.com/loft/archive/2009/01/understanding-this-this-and-event-in-a-jquery-callback-function
So I have a newly created Javascript object called EditableObject in my custom .js file
function EditableObject(e, dv, i) {
this.element = e;
this.default_value = dv;
this.set = 0;
this.id = i;
alert(this.element.html());
this.element.click(function (event) {
alert(this.element.html());
});
}
In my main page, I have a div called "field" that has the text "yeah" in it like such:
<div id="field">yeah</div>
In the script portion of my main page, I've got:
var t = new EditableObject($("#field"), "value", 1);
When the page loads, there is an alert box that says "yeah". But when I click on the div, I get an error saying that "this.element is undefined". Why is this happening?
Inside your click handler, this refers to a different scope (depending on browser, it'll be the event object or the current function). You need a closure to access parent scope's this:
var self = this;
this.element.click(function (event) {
alert(self.element.html());
});
The thing with this is that it differs in each function depending on the context. In jQuery bind functions, it is the element itself so the most straight-forward solution is:
this.element.click(function (event) {
alert($(this).html());
// this is element, $(this) is jQuery object containing element
});
So currently, this refers to the element, which differs from e.g. the line
this.id = i;
where it refers to the instance of EditableObject, because there you use this in a different function.
The this in your click function refers only to the click itself. I believe you can use
e.html();
there instead
this inside of your click handler refers to the DOM object, not the instance of EditableObject.
You could modify it like this:
this.element.click(function (event) {
alert($(this).html());
});
I have what seems to be a very tricky situation. I would like to pass an instance of an object to the event listener of a DOM element that was created by that same object instance (if that makes sense).
function Object(callback){
this.callback = callback;
this.node = document.createElement('div');
this.send = function(){
document.getElementById('list').appendChild(this.node);
}
this.node.addEventListener('click',function(){/*this.callback() of Object instance needs to go here*/},true);
}
I know that using callback() would work inside the event listener, but thats not what I need because I will be using variables from the instance that are not passed from the construct later on.
How can I solve this?
The anonymous function changes the meaning of this. To be able to use it within the handler, use another var, or don't create another function:
var elem = this;
this.node.addEventListener('click',function(){ elem.callback(); },true);
or
this.node.addEventListener('click', this.callback, true);