I have the following method
PMm.test = function (){
....plenty of code....
$('.element',this.page).click(function(e){
e.preventDefault();
var self = $(this);
console.log(self);
this.load(someoptions)
}.bind(this));
...plenty of code....
}
PMm.test.prototype.load = function(options){
...some code
}
When console.log(self), it returns the method PMm.test. How do i access the element clicked if $(this) is the entire function scope where i declare my event ? Knowing that i also need to call the .load() method which is declared later on.
I think it'd be best to store the context in a variable an access it using closure in your callback. It'd lead to a more readable code.
PMm.test = function (){
....plenty of code....
// Store the context in a variable.
var that = this;
$('.element',this.page).click(function(e){
e.preventDefault();
// this here references the DOM element (as expected)
var self = $(this);
console.log(self);
// you can access your methods through that.
that.load(someoptions)
});
...plenty of code....
}
PMm.test.prototype.load = function(options){
...some code
}
Hope it helps.
Since you're using this for something else (because of the bind), you can use either:
e.target - This is the element the event actually occurred on, which may be a descendant of the element that you attached the handler to.
or
e.currentTarget - This is the element the handler is attached to. (What's normally this in jQuery callbacks if you don't use bind.)
E.g.:
PMm.test = function (){
// ....plenty of code....
$('.element',this.page).click(function(e){
e.preventDefault();
var elementClicked = $(e.currentTarget); // or $(e.target);
// ...use it...
this.load(someoptions)
}.bind(this));
Example:
function ClickResponder(name, selector) {
this.name = name;
$(selector).on("click", this.handler.bind(this));
}
ClickResponder.prototype.handler = function(e) {
console.log("this.name = " + this.name);
console.log("e.target.tagName = " + e.target.tagName);
console.log("e.currentTarget.tagName = " + e.currentTarget.tagName);
};
new ClickResponder("respond-o-matic", ".foo");
<div>
<div class="foo">
<span>Click me</span>
</div>
<div class="foo">
<span>Click me</span>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Using [function].bind(this) you are binding this (PMm.test) to the jquery event, overwriting this (element) set by jquery.
If you need both inside the function you don't need to bind the object, instead, making the object PMm.test accesible using a variable:
PMm.test = function (){
....plenty of code....
var obj=this; //obj references to PMm.test
$('.element',this.page).click(function(e){
e.preventDefault();
var self = $(this);
console.log(self);
obj.load(someoptions)
}); //no .bind()
...plenty of code....
}
PMm.test.prototype.load = function(options){
...some code
}
Related
I'm trying to use a delegated event handler on dynamically-loaded content, like so:
AjaxProt.prototype = {
// bind handler - ensure to use $(document) to delay call to .on() method
init: function () {
var thisObj = this;
$(document).on(thisObj.event, thisObj.targetEl, function (e) {
e.preventDefault();
var url = $(thisObj.targetEl).attr('href');
thisObj.ajaxRequest(url);
});
},
ajaxRequest: function (url) {
var thisObj = this,
method = this.method,
ajaxCallType = this.ajaxCallType,
callback;
// $.ajax here
targetEl is assigned to [id^=startOfClassName]. I tried to pass the href value from init() to ajaxRequest(), but it's still only selecting the first element matching the selector on the page. How might I be able to ensure that the href value is bound to the element that's actually clicked? Thanks!
Sorry for wasting time, I figured this out myself.
All I had to do was change var url = $(thisObj.targetEl).attr('href') to var url = $(this).attr('href') since this is now in the scope of thisObj.targetEl, and therefore points to the specific element clicked.
p.num = 100;
$('body').on('click', '.del', this.delete.bind(this));
p.delete = function(e) {
console.log(this.num); //100
//how can I get the .del element?
}
I'm trying to get the element that produced the click, but I also need access to the num property.
How can I access both types of 'this' inside my delete method?
The callback for an event receives an Event object that you can use to retrieve the element on which the event was called.
function(e) {
var element = $(e.target); //This is the element that the event was called on.
}
Disclaimer : This is the my exact answer (adapted with the current code) taken from here : Pass additional arguments to event handler?
Yet, the question doesn't seem to be an exact duplicate (but i may be wrong).
As said in the documentation of .on, you can pass datas to your event.
.on( events [, selector ] [, data ], handler )
data
Type: Anything
Data to be passed to the handler in event.data when an event is triggered.
So your event could look like that :
p.num = 100;
$('body').on('click', '.del', {object : this}, this.delete);
p.delete = function(e) {
var myObj = e.data.object;
// [myObj] will be your plugin
// [this] will be the clicked element
// [e] will be you event
}
if you're using jquery, you can combine those functions all into one like below:
note: num is an attribute so you have to use .attr().
$(document).ready(function() {
$('body').on('click', '.del', function() {
var num = $(this).attr('num');
alert('click function and num = ' + num);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Delete
or if you really want to keep them separate functions....:
$(document).ready(function() {
$('.del').on('click', function() {
deleteThis($(this));
});
});
function deleteThis(element){
var num = element.attr('num');
alert('click function and num = ' + num);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Delete
also, if youre using separate functions for the click and the delete, pass the element from click to delete: pass element - callDeleteFunction($(this)), and retrieve element - myDeleteFunction(element aka $(this))
I'm not sure what you're asking about but maybe this is what you want:
var p = {};
p.num = 100;
$('body').on('click', '.del', p.delete); // don't bind to this
p.delete = function(e) {
console.log(p.num); // here you still can call p
// this is del DOM element
}
I have a simple js class where i am trying to bind 'click' event on an object to the functions. I am iterating through a list of elements:
<ul id="cp">
<li><button id="panel_button_light">Turn Light On</button></li>
<li>
<div class="arrow-up" id="panel_button_temp_up"></div>
<div class="arrow-down" id="panel_button_temp_down"></div>
</li>
</ul>
I am not sure what i need to enter in the code below when iterating through the elements so that I can call the class method when clicking them.
This is the js code that i am using:
<script type="text/javascript">
var CP = function(widget){
this.widget_name = widget;
var self = this;
this.init = function(){
$('#'+this.widget_name).children('li').children('*[id*=panel_]').each(function(self){
//I need function here to bind the click event to the class CP
$("#" + this.id).on('click', $.proxy(this.id, this));
});
}
};
CP.prototype.panel_button_temp_up= function(){
};
CP.prototype.panel_button_temp_down= function(){
};
CP.prototype.panel_button_light = function(){
};
$( document ).ready(function(){
var c = new CP("cp");
c.init();
});
this.id is a string, so $.proxy(this.id, this) doesn't make sense. If you want to access the property with the same name on the instance of cp, you have to do something like instance[this.id].
For example:
var self = this;
this.init = function() {
$('#'+this.widget_name).find('[id^=panel_]').each(function() {
$(this).on('click', self[this.id]);
});
};
So I have the following fragment:
$(".server").each(function() {
var element = $(this);
//bunch of javascript here with element
});
I also want to bind a single click event for an id to do the same work as the above, how is this possible, without copying and pasting the entire block and doing:
$("#my-id").click(function() {
var element = $(this);
//bunch of javascript here with element
});
I think the following should work:
var eventHandler = function() {
var element = $(this);
//bunch of javascript here with element
};
$(".server").each(eventHandler);
$("#my-id").click(eventHandler);
I'm trying to create a custom function that unbinds and then binds an event. It looks like this:
App.bindEvent = function(selector, eventType, eventHandler) {
$(selector).unbind(eventType);
$(selector).bind(eventType, function(event) {
eventHandler(event);
});
};
However, the problem I am facing is that I cannot use the this keyword to reference the DOM element that was clicked. For example, I cannot do this:
App.bindEvent("#my-element", "click", function() {
var myId = $(this).attr("data-my-id");
});
How would I go about getting the this keyword to point to the clicked DOM element like it does in jQuery.bind()?
Thanks for any help.
Change:
eventHandler(event);
To:
eventHandler.call(this, event);
That'll change the "scope" of your function to be the same as the scope of the original "bind" call.
How about this instead:
App.bindEvent = function(selector, eventType, eventHandler) {
var element = this;
$(selector).unbind(eventType);
$(selector).bind(eventType, function(event) {
eventHandler.call(element, event);
});
};
You need to call the handler in the context of the object:
eventHandler.call(this, event);
I think you're trying to refer to
event.target
For example:
App.bindEvent("#my-element", "click", function(event) {
var myId = $(event.target).attr("data-my-id");
});
check out jquery's event documentation