Merging event listeners - javascript

I have these event listeners:
$(document).on("pagebeforeshow",function(e,ui){
// do something
});
$(document).on("click","[data-json]",function(){
// do something else
});
I can merge them like so:
$(document).on({
pagebeforeshow: function(e, ui) {
// do something here
},
click: function(e) {
// do something else here
}
});
... but I'm not sure how to bind the click to [data-json] as in the first example.

You could use this line
click: function(e) {
if(!$(e.target).is($("[data-json]"))) return;
}
it will simulate what you first example was doing. It only runs the function if element that is firing has attribute data-json

Related

Bind custom event to dynamic created elements

I've been binding events to dynamically created elements without any kind of issues by using:
$(document).on(event, element, function)
Now I want to bind a custom event and I just can´t get it to work.
The event is a JS plugin to handle single e double click. If I use it like this:
$('#test').oneordoubleclick({
oneclick: function () {
alert('you have clicked this node.');
},
dblclick: function () {
alert('you have double clicked this node.');
}
});
It works like a charm, but, as I transform the code to bind the event to dynamically created elements, like this:
$(document).on('oneordoubleclick', '#test', {
oneclick: function () {
alert('you have clicked this node.');
},
dblclick: function () {
alert('you have double clicked this node.');
}
});
It stops working!
It wasn't supposed to work? What am i doing wrong? It is possible to do what i want to accomplish?
According to my understanding, .oneordoubleclick is not an Event, just like .footable or .tooltip. Therefore, you cannot put it in $(document).on("oneordoubleclick","#test", ...)
Here's my solution, with the aid of the plugin source code:
// Custom functions
let singleClick = function () { // your function when is single click
alert('you have clicked this node.');
}
let doubleClick = function () { // your function when is double click
alert('you have double clicked this node.');
}
// Necessary to differentiate is single or double click
let timer,
do_click = function (e, fx) {
clearTimeout(timer);
timer = setTimeout(function () {
fx();
}, 400); // if there is no another click between 0.4s, then it is single click
},
do_dblclick = function (e, fx) {
clearTimeout(timer); // the single click function will not be called
fx();
};
// Listener
$(document) .on("click", "#test", function (e) { do_click(e, singleClick) })
.on("dblclick", "#test", function (e) { do_dblclick(e, doubleClick) })
Correct me if I'm wrong.
In addition to the correct answer, i needed to know which DOM element was responsible for the call. To achieve that i changed a little bit XH栩恒 answer code...
// Necessary to differentiate is single or double click
let timer,
do_click = function (e, fx, element) {
clearTimeout(timer);
timer = setTimeout(function () {
fx(element);
}, 400); // if there is no another click between 0.4s, then it is single click
},
do_dblclick = function (e, fx, element) {
clearTimeout(timer); // the single click function will not be called
fx(element);
};
// Listener
$(document).on("click", ".teste", function (e) {
do_click(e, singleClick, $(this))
})
.on("dblclick", ".teste", function (e) {
do_dblclick(e, doubleClick, $(this))
})
let singleClick = function (element) { // your function when is single click
console.log(element)
}
let doubleClick = function (element) { // your function when is double click
console.log(element)
}

Copy click events, destroy them and attach them later

I'm trying to completely disable the click events for some elements but to have the option to reenable them later.
What I have try so far:
$('a').on('click', function(e) {
// some stuffs...
});
...
$('a').each(function(i, el) {
this.clickEvents = $._data(el, 'events').click;
$(el).off('click');
});
// reenable them later (this is not working)
$('a').each(function(i, el) {
$(el).on('click', this.clickEvents);
});
...
Any ideas where I'm wrong?
Try .handler in each clickEvent:
$('a').each(function(i, el) {
// clickEventHandlers is an array of handler functions
this.clickEventHandlers = $._data(el, 'events').click.map(function(e) {
return e.handler;
});
$(el).off('click');
});
// re-enable them later
$('a').each(function(i, el) {
// reapply the handlers in order
this.clickEventHandlers.forEach(function(handler) {
$(el).on('click', handler);
});
});
The great thing about this is that you re-apply all event listeners in order.
Working JSFiddle.
Try $._data(el, 'events').click[0].handler for first click event , or use $.each() to iterate all click or other events ; store handler at element .data() ; e.g., .data("events") ; reattach handler using $(this).data().events[0]
$("a").data("events", []).on("click", function() {
console.log(this)
});
$("a").each(function(i, el) {
$.each($._data(el, 'events').click, function(index, event) {
$(el).data().events.push(event.handler)
})
console.log($(this).data("events"));
$(el).off("click");
});
// reenable them later (this is not working)
$("a").each(function(i, el) {
$.each($(this).data().events, function(index, handler) {
$(el).on("click", handler);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
click

Binding multiple event handler pairs on dynamically generated elements in jquery with on

I have some dynamically generated elements with the class my-class on which I want to bind some events. I have the below code which works properly.
$(document).on("event1", ".my-class", function () {
alert("Event 1");
});
$(document).on("event2", ".my-class", function () {
alert("Event 2");
});
I want to refactor it so that there can be a single call to on for the category. Something like this
$(document).on(".my-class", {
"event1": function() {alert("Event1")},
"event2": function() {alert("Event2")}
});
Is this possible in jquery?
There might be a better way, but I've used this before and it worked for me:
Demo Fiddle
I wouldn't delegate off the document, instead I'd use the closest parent container.
JS:
$('body').on('click mouseenter', 'div', function(e) {
if (e.type === 'click') {
$('div').html('clicked');
}
else { //you'd need an else if here if you had more than two event types
$('div').html('mouse enter');
}
});

Unbind and rebind click on css transition end

I'm having troubles with the .bind() and .unbind() features. When the button is clicked, it's supposed to change the color of the box. During this time, the button is disabled by unbinding the click function. However, I'm having issues rebinding the click when the css transition completes.
What I have so far is:
$('button').on('click', function(){
$('button').unbind('click');
$('.box').toggleClass('color');
$('.box').one('webkitTransitionEnd transitionend', function(e){
console.log('transition ended')
$('button').bind('click')
});
});
http://jsfiddle.net/t6xEf/
You need to pass the click handler when binding it. So create a function reference then use it while binding the handler.
function click() {
$('button').off('click.transition');
$('.box').toggleClass('color');
}
$('.box').on('webkitTransitionEnd transitionend', function (e) {
console.log('transition ended')
$('button').on('click.transition', click)
});
$('button').on('click.transition', click);
Demo: Fiddle
Also look at the usage of namespaces while registering/removing the handler because if there if some other click handler added to the button we don't want to disturb it
Also do not add a event handler inside another one
Also have a look at .one()
function click() {
$('.box').toggleClass('color');
}
$('.box').on('webkitTransitionEnd transitionend', function (e) {
console.log('transition ended')
$('button').one('click.transition', click)
});
$('button').one('click.transition', click);
Demo: Fiddle
I would use a flag instead of binding/rebinding the event handler:
var animating = false;
$('button').on('click', function() {
if (animating) return;
animating = true;
$('.box').toggleClass('color')
.on('webkitTransitionEnd transitionend', function(e) {
animating = false;
});
});
http://jsfiddle.net/t6xEf/1/
Do not unbind. Use a boolean:
var onTrans = false;
$('button').on('click', toggle);
function toggle() {
if (!onTrans){
$('.box').toggleClass('color');
onTrans = true;
$('.box').on('webkitTransitionEnd transitionend', function (e) {
onTrans = false;
});
}
}
http://jsfiddle.net/jp8Vy/
This is surely not what you want to do. It seems overly complex, and I can't imagine a good use case scenario.
That being said, you need to reattach the functionality to be performed in the final bind statement. You call the function to bind to the click event, but don't tell the function what to attach.
You need something like this:
$('button').bind('click', function() { ... });
However, that probably isn't what you really want. It sounds like you just want to set the button's "disabled" attribute to false, then to true after the animation.

Correct syntax for defining an event delegator

Normally you write a handler for a button click like this:
$(document).ready(function()
{
$("button").click(function()
{
doSomething();
});
});
But in the case of an event delegator, to respond to an event with a function such as this:
function doSomething(event)
{
if (ev.target.id == 'button1' )
{
//do your stuff
console.log('#button1 click');
}
else
{
console.log('not a #button1 click');
}
}
What I'm confused about is the correct syntax for defining the event that calls this delegator function - this? (A):
$(document).ready(function()
{
$(function()
{
$('button').click(doSomething);
});
});
or this? (B):
$(document).ready(function()
{
$("button").click(doSomething);
});
Which is correct and why?
In choice A you are just repeating the document.ready syntax twice.
// These two lines are equal
$(document).ready(fn);
$(fn);
All you need to do is choice B
While choice B would certainly be the way to do this if you needed to use a separate function, i.e., in the case where you needed to invoke the function from somewhere other than a button click, my preference is usually to put the code in line. The only other times I don't do this is when it would improve readability.
$(function() {
$("button").click( function(e) {
if (e.target.id == 'button1') {
alert('button1 clicked');
}
...
});
});

Categories