JSfiddle jsfiddle
I would like to use this concept of event delegation on each name spaced event. Appernetly it is more optimized than .big-ul li
. I unfortunately cannot find the proper syntax to make it work while using namespaces or while trying to attach multiple event handlers simultaneously using a plain object?
$(".big-ul").on({
"click.namespace", "li": function(event){
$(this).toggleClass("active");
},
"mouseenter.namespace" , "li": function(event){
$(this).addClass("inside");
},
"mouseleave.namespace", "li": function(event){
$(this).removeClass("inside");
}
});
example of event delegation from jquery's site
$("#dataTable tbody").on("click", "tr", function(event){
alert($(this).text());
});
JSfiddle jsfiddle
I would like to use this concept of event delegation on each name spaced event. Appernetly it is more optimized than .big-ul li
. I unfortunately cannot find the proper syntax to make it work while using namespaces or while trying to attach multiple event handlers simultaneously using a plain object?
$(".big-ul").on({
"click.namespace", "li": function(event){
$(this).toggleClass("active");
},
"mouseenter.namespace" , "li": function(event){
$(this).addClass("inside");
},
"mouseleave.namespace", "li": function(event){
$(this).removeClass("inside");
}
});
example of event delegation from jquery's site
$("#dataTable tbody").on("click", "tr", function(event){
alert($(this).text());
});
Share
Improve this question
edited Aug 14, 2013 at 11:40
nirazul
3,9654 gold badges29 silver badges48 bronze badges
asked Aug 14, 2013 at 9:48
John AbrahamJohn Abraham
18.8k36 gold badges132 silver badges240 bronze badges
10
- +1 for even attempting it like that :) Do you have a JSFiddle for this? – iCollect.it Ltd Commented Aug 14, 2013 at 9:56
- You have assigned the events to the selectors (i.e. "li") instead of the event type. That just looks wrong pared to the multi-event examples. – iCollect.it Ltd Commented Aug 14, 2013 at 9:58
- I know the li is wrong .. .wondering how to make it right lol – John Abraham Commented Aug 14, 2013 at 9:58
- Added a JSFiddle with answer so you can play with options, but basically do not overplicate your code for the sake of a slight/negligible speed improvement. K.I.S.S. is the way to go. – iCollect.it Ltd Commented Aug 14, 2013 at 10:10
- I dont see the jsfiddles link... I totally understand the K.I.S.S mentality but learning these things make typically improve my structure and overall understanding of jquery/javascript (seeing that I'm still pretty novice) I just want to see the limitation. More of an excerise then a practical use. – John Abraham Commented Aug 14, 2013 at 10:12
5 Answers
Reset to default 3You can't attach multiple events to multiple functions like that. What you could do is using an each
function on an object containing all the needed infos. You could even store your namespace-name (haha) in a separate variable:
Example on jsFiddle
var $root = $(".big-ul");
var namespace = 'namespace';
var events = [
{
event: "click"+"."+namespace,
delegate: "li",
fn: function(event){
$(this).toggleClass("active");
}
},
{
event: "mouseenter"+"."+namespace,
delegate: "li",
fn: function(event){
$(this).addClass("inside");
}
},
{
event: "mouseleave"+"."+namespace,
delegate: "li",
fn: function(event){
$(this).removeClass("inside");
}
}
]
for(i=0;i<events.length;i++){
$root.on(events[i].event, events[i].delegate, events[i].fn);
}
The advantage pared with the accepted solution:
- It's a far more flexible solution as you could send the
events
-Object across modules or dynamically bind events with one single function, when you always use the sameevent
-Object structure. - You can delegate from one root object to different child nodes, not only one.
Example:
/* events array*/
var events = [
{
root: "root-query-string",
event: "eventname",
delegate: "delegate-query-string",
fn: function
}
]
/* dynamic batch bind function */
function batchBind(events) {
for(i=0; i<events.length; i++){
$(el.root).on(events[i].event, events[i].delegate, events[i].fn);
}
}
how about something like this?
$(".big-ul").on("click.namespace mouseenter.namespace mouseleave.namespace", "li", function(event){
var eventMatch = event.handleObj.origType + "." + event.handleObj.namespace;
if(eventMatch == "click.namespace"){
$(this).toggleClass("active");
}
if(eventMatch == "mouseenter.namespace"){
$(this).addClass("inside");
}
if(eventMatch == "mouseleave.namespace"){
$(this).removeClass("inside");
}
});
would that not work?
EDIT you could also replace the mutiple if statements with a switch statement if you preferred... it would probably give better performance too (if you are worried about that).
$(".big-ul").on("click.namespace mouseenter.namespace mouseleave.namespace", "li", function(event){
var eventMatch = event.handleObj.origType + "." + event.handleObj.namespace;
switch(eventMatch){
case "click.namespace":
$(this).toggleClass("active");
break;
case "mouseenter.namespace":
$(this).addClass("inside");
break;
case "mouseleave.namespace":
$(this).removeClass("inside");
break;
}
});
EDIT2 updated so jsfiddle will work based on what @Nirazul said. Example on jsFiddle
The each
answer given will not be more efficient than using the .big-ul li
selector. My theory being that a basic on() selector runs against the selector once and connects the event immediately whereas the deferred on() with selector runs the selectors each time the events occur (to find the matching elements).
You might as well do it this way and keep it simple:
$(".big-ul li").on({
"click.namespace": function (event) {
$(this).toggleClass("active");
},
"mouseenter.namespace": function (event) {
$(this).addClass("inside");
},
"mouseleave.namespace": function (event) {
$(this).removeClass("inside");
}
});
http://jsfiddle/AzQBR/1/
I am happy to be overruled about the speed of deferred on() pared to non-deferred on() calls if someone can run performance stats.
Having looked over all the answers again (including my original one), I would remend simply connecting each event separately using the deferred on()
syntax:
var $bigul = $(".big-ul");
$bigul.on("click.namespace", "li", function (event) {
$(this).toggleClass("active");
});
$bigul.on("mouseenter.namespace", "li", function (event) {
$(this).addClass("inside");
});
$bigul.on("mouseleave.namespace", "li", function (event) {
$(this).removeClass("inside");
});
All the other solutions over-plicate the code. This is about a straight forward as you can get.
JSFiddle http://jsfiddle/AzQBR/2/
It is possible guys! But you wrote it in wrong way! Try this :
$(document).ready(function(){
$(document).on({
mouseenter: function(){
$(this).css("background-color", "lightgray");
},
mouseleave: function(){
$(this).css("background-color", "lightblue");
},
click: function(){
$(this).css("background-color", "yellow");
}
},'p');
});