jQuery onClick multiple callbacks - javascript

How do I register multiple callbacks for a jQuery event? An example of what I am trying to achieve:
$(document).on("click", ".someclass", CallbackFunction1, CallbackFunction2);
function CallbackFunction1(event) {
//Do stuff
}
function CallbackFunction2(event) {
//Do some other stuff
}
How can I set up the event handler to execute both callback functions when the element is clicked?

You can just attach them as separate event handlers:
$(document).on("click", ".someclass", CallbackFunction1)
.on("click", ".someclass", CallbackFunction2);

Unless I misunderstand what you're asking, you can use a single event handler:
$(document).on('click', '.someclass', function(e){
CallbackFunction1(e);
CallbackFunction2(e);
});

You can use a third function and then recall the other ones:
$(document).on("click", ".someclass", CallbackFunction);
function CallbackFunction(event) {
CallbackFunction1(event);
CallbackFunction2(event);
}
function CallbackFunction1(event) {
//Do stuff
}
function CallbackFunction2(event) {
//Do some other stuff
}

If you will be reusing this to bind different list of handlers for different elements, i would create a factory.
function multiFunction(){
var methods = Array.prototype.slice.call(arguments, 0);
return function(e){
for (var f=0, l = methods.length; f<l; f++) {
methods[f].apply(this, arguments);
}
}
}
and call this like this
$(document)
.on('click', 'someclass', multiFunction( CallbackFunction1, CallbackFunction2));
.on('click', 'someotherclass', multiFunction( CallbackFunction8, CallbackFunction1, CallbackFunction5));
Demo at http://jsfiddle.net/gaby/D8K75/

Related

Re-binding JQuery events

I have a series of JQuery events, as an example, below
<script>
$("#target").click(function() {
..
});
$("#anothertarget").mouseout(function() {
...
});
$("#someselector").scroll(function() {
...
});
... other JQuery events
</script>
How do I "unbind" all these events from the document so they will all stop working and re-bind them all again later without hard coding them ?
There's a couple things you can do but either way you'd need to set conditions for the events:
You could create an event that would have a conditional that will turn the event on or off.
You could set a variable within the condition that would be either true or false, and then have that variable lead to a bind or unbind event.
if(some condition is true){
$("#target").on("click", function() {
});
}
//your scenario may not fit this code exactly but you would need to have conditions that bind or unbind events
var temp = true;
if(some condition is true){
$("#target").on("click", function() {
temp = false
});
};
if (temp == false){
$('#target').off("click",function(){
})
};
//the answer below by JagsSparrow is a pretty good way too
You can create bindAll & unBindAll functions and call them dynamically whenever required.
function bindAll(){
$("#target").click(function() {
..
});
$("#anothertarget").mouseout(function() {
...
});
$("#someselector").scroll(function() {
...
});
}
function unBindAll(){
$("#target").off('click');
$("#anothertarget").off('mouseout');
$("#someselector").off('scroll');
}
//To bind function call
bindAll();
//To unbind function call
unBindAll();
EDIT:
We can store object of events and bind and unbind them as below
var allEvents = {
'#target':{
event:'click',
func:function(){
console.log('click')
}
},
'#anothertarget':{
event:'mouseout',
func:function(){
console.log('mouseout')
}
},
'#someselector':{
event:'scroll',
func:function(){
console.log('scroll')
}
}
}
function bindUnbindAll(isBind){
for(var selector in allEvents){
// Here we can carefully filter some events to bind and unbind
var obj = allEvents[selector];
if(isBind)
$(selector).on(obj.event,obj.func.bind(this));
else
$(selector).off(obj.event);
}
}
//to bind function call
bindUnbindAll(true);
//To unbind function call
bindUnbindAll(false);
To unbind Off, unbind can be used to remove the event, like:
$('#target').unbind('click');
To bind
$('#target').bind('click', function() { /* Do stuff */ });
You can put code in functions to bind/unbind events on your objects. Hope this helps!

Pass $(this) to a Binded Callback Function

I am trying to understand the difference between these two callback methods and how they handle the $(this) context.
Working Example
$("#container").on("click",".button", function() {
$(this).text("foo");
});
This process works just fine. However, if I want to do a different approach, I lose the context of the event.
Non-Working Example
bindAnEventToAnElement: function(theElement, theEvent, theFunctions) {
$("body").on(theEvent, theElement, function() {
theFunctions();
});
}
bindAnEventToAnElement(".button", "click", function() {
$(this).text("foo");
});
The latter produces an undefined error. Is there a way I can handle callbacks like this while retaining the context of the event?
Fiddle
http://jsfiddle.net/szrjt6ta/
AFAIK, jquery's this in that callback function refers to the event.currentTarget value. So, you should also pass the event object and do something like this:
$("#container").on("click", ".button", function () {
$(this).text("foo");
});
theApp = {
bindAnEventToAnElement: function (theElement, theEvent, theFunctions) {
$("body").on(theEvent, theElement, function (e) {
theFunctions.apply(this /* or e.currentTarget */, arguments);
});
}
}
theApp.bindAnEventToAnElement(".button-two", "click", function () {
$(this).text("foo");
});
Working Fiddle
If I try to explain the problem, jquery is binding the callback function to pass this as e.currentTarget. But you are passing an another callback function inside that callback function whose scope will not be its parent callback function but will be the window. So, you need to again bind the this to the wrapped function, which you can do using apply or call.
You have to manually bind the context to the function in order to have this valorized inside your callback:
$("body").on(theEvent, theElement, function() {
theFunctions.apply(this);
});
example http://jsfiddle.net/szrjt6ta/1/
Find more about apply() here
you can pass the event, then use $(e.target)
https://jsfiddle.net/szrjt6ta/3/
Use .call(this) The call() method calls a function with a given this value and arguments provided individually.
Note: While the syntax of this function is almost identical to that of
apply(), the fundamental difference is that call() accepts an argument
list, while apply() accepts a single array of arguments.
$("#container").on("click",".button", function() {
$(this).text("foo");
});
theApp = {
bindAnEventToAnElement: function(theEvent, theElement, theFunctions) {
$("body").on(theEvent, theElement, function() {
theFunctions.call(this);
});
}
}
theApp.bindAnEventToAnElement("click", ".button-two", function() {
$(this).text("fooe");
});
Fiddle
Change the event handler attachment from
$("body").on(theEvent, theElement, function() {theFunctions();});
to
$("body " + theElement).on(theEvent, theFunctions);
Like this:
HTML:
<div id="container">
<a class="button">Button</a><br />
<a class="button-two">Button Binded</a>
</div>
JQuery:
$("#container").on("click",".button", function() {
$(this).text("foo");
});
theApp = {
bindAnEventToAnElement: function(theElement, theEvent, theFunctions) {
$("body " + theElement).on(theEvent, theFunctions);
}
}
theApp.bindAnEventToAnElement(".button-two", "click", function() {
$(this).text("foo");
});
Fiddle: https://jsfiddle.net/szrjt6ta/10/

How to call the same function in two different ways?

I am trying to combine a function which will display alert (ofcourse I have a lot of code In this function but for this case It will be alert) after:
Click on element with class .number
Change select[name=receive]
I have this code but it doesn't work:
$(document).on(("click",".number"),("change","select[name=receive]"),function(){
alert('test');
})
Try this
function doMyWork() {
console.lot( 'TEST' );
}
$('.number').on('click', doMyWork);
$('select[name=receive]').on('change', doMyWork);
Or, if your elements are inserted after DOM ready:
You do not have to use this form if the target elements exist at DOM ready
function doMyWork() {
console.lot( 'TEST' );
}
$(document).on('click', '.number', doMyWork)
.on('change', 'select[name=receive]', doMyWork);
Try this
$(document).on("click change","select[name=receive], .number", function(){
alert('test');
});
Or
var fn = function () {
alert('test');
}
$(document).on("click", ".number", fn);
$(document).on("change", "select[name=receive]", fn);
You cannot separate events and selectors in a single .on() call. You have two options here. You can use them together....
$(document).on("click change", ".number, select[name=receive]"),function(){
alert('test');
});
...however this means that .number will listen to both click and change, possible resulting in the function running 2 times.
You need to move the function outside and reuse it for every handler
var al = function(){
alert('test');
};
$('.number').on('click', al);
$('select[name=receive]').on('change', al);
$(document).on("click change",".number, select[name=receive]", function(){
alert('test');
})
I am not sure where you learned that syntax, but that is not how on() works.
Use a named function and share it.
(function(){
var shared = function(){
console.log(this);
}
$(document)
.on("click",".number", shared)
.on("change","select[name=receive]", shared);
}());

User-defined callback function is being fired multiple times in Javascript/jQuery

There are some similar questions, but they all seem like regarding native jQuery callback functions.
So I have this code which (live) creates a div containting some form elements.
Values of these elements should be retrieved inside a callback function when (before) the div is removed.
function popup(callback) {
// ...
// before removing the div
callback.call();
// remove div
}
Unexpectedly, the callback function is being fired multiple times (increasingly) after the first time popup is executed.
I have simplified the code, and here is the fiddle.
I hope this is what you need.
function popup(callback) {
$("body").append('<div><span id="test">test</span> close</div>');
$(document).on("click", "#close", function() {
callback.call();
//
//callback = function() {};
$(document).off("click", "#close");
$("div").remove();
});
};
$(document).on("click", "#open", function() {
popup(function() {
alert('$("#test").length = ' + $("#test").length);
});
});
Basically, you need to remove event handler by invoking off() method.
Try dynamically generating the elements instead of using a string. This will allow you to bind events easier.
function popup(callback)
{ var $elem = $("<div></div>");
$elem.append($("<span></span>").html("test"));
$elem.append(" ");
$elem.append($("<a></a>").html("close").attr("href", "#"));
$("body").append($elem);
$elem.find("a").click(function() {
callback.call();
$elem.remove();
});
};
$(document).on("click", "#open", function() {
popup(function() {
alert('$("#test").length = ' + $("#test").length);
});
});
Example: http://jsfiddle.net/4se7M/2/
I don't know the exact scenario, but why do you want to bind and unbind the event each time you show the popup?
You can bind only once, like this, can't you?
$(document).on("click", "#close", function() {
alert('$("#test").length = ' + $("#test").length);
$("div").remove();
});
function popup() {
$("body").append('<div><span id="test">test</span> close</div>');
};
$(document).on("click", "#open", function() {
popup();
});

jquery: function to end another function

$('#start') executes the function myFunction() and $('#stop') end it. How do I stop myFunction() from executing?
function myFunction() {
$(document).mousemove(function(e) {
$('#field').html(e.pageY)
});
}
$('#start').click(function() {
myFunction();
});
$('#stop').click(function() {
//stop myFunction
});
As Daniel pointed out, you actually want to unbind the event handler. You can use unbind for this:
$('#stop').click(function() {
$(document).unbind('mousemove');
});
But this will also remove all other mousemove event handlers, that might be attached by other plugins or similar (I mean, you attach to the document element not a "custom" element, so it can be that other JavaScript code also binds handlers to this element).
To prevent this, you can use event namespaces. You would attach the listener with:
function myFunction() {
$(document).bind('mousemove.namespace', function(e) {
$('#field').html(e.pageY);
});
}
and unbind:
$('#stop').click(function() {
$(document).unbind('mousemove.namespace');
});
This would only remove your specific handler.
You want to use the jQuery bind and unbind methods. For example:
function myFunction() {
$(document).mousemove(function(e) {
$('#field').html(e.pageY)
});
}
$('#start').bind('click.myFunction', function() {
myFunction();
});
$('#stop').bind('click', function() {
$('#start').unbind('click.myFunction');
});
You're not stopping the function from executing. Your myFunction() simply attaches a callback to an event listener, which is called whenever the mouse is moved on the document. The callback function is invoked and is terminated immediately.
You'd simply want to unbind the callback from the event listener. Check out the other answers for concrete examples.
A better way would be to use bind and unbind, like so:
function myFunction() {
$(document).mousemove(function(e) {
$('#field').html(e.pageY)
});
}
$('#start').bind('click', myFunction);
$('#stop').click(function() {
$('#start').unbind('click', myFunction);
});

Categories

Resources