Reputation: 782
//I hava this tool function to bind event
var bindEvent = function($dom,events,data,_this){
for(var key in events){
$dom.bind(key,function(){
events[key].apply(_this,[data]);
});
}
};
//and use like this
var events = {
click:function(){
alert("click");
},
dblclick:function(){
alert("dblclick");
}
};
var $btn = $("#btn");
bindEvent($btn,events,"mydata",$btn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">MYBtn</button>
when i click on the button, dblclick event is always being triggered.
I know, the reason of this problem.
There is a closure when bind event which is used in "for" loop. Upon termination of loop, the last object in memory (there is dbclick callback function).
so, when trigger click
event, it run alert("dblclick")
.
I want to know if had a good way to solve this problem.
Or have a good way to implement tool function for bind event.
Thank you very much.
Upvotes: 2
Views: 680
Reputation: 12452
I don't know why you would need data
, but in general you don't need a loop for adding more than one event. You can just pass the object to bind
or on
. And because in an event this
is always the element, you don't need to set the context.
$("#btn").on({
click: function() {
console.log("click");
},
dblclick: function() {
console.log("dblclick");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">MYBtn</button>
Or as long version with your wrapper function:
var bindEvent = function($dom, events) {
$dom.bind(events);
};
var events = {
click: function(){
console.log("click");
},
dblclick: function(){
console.log("dblclick");
}
};
var $btn = $("#btn");
bindEvent($btn, events);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">MYBtn</button>
Upvotes: 3
Reputation: 1087
I dont know the exact answer, but I tried:
var bindEvent = function(dom,events,data,_this){
dom.bind(events,function(){
for(var key in events){
events[key].apply(_this,[data]);
}
});
}
Upvotes: 0
Reputation: 36609
Create a closure
inside for-in
loop(while attaching event
) where inner-function
will remember the environment in which it is created!
var bindEvent = function($dom, events, data, _this) {
for (var key in events) {
$dom.bind(key, (function(key) {
return function() {
events[key].apply(_this, [data]);
}
})(key));
}
};
var events = {
click: function() {
console.log("click");
},
dblclick: function() {
console.log("dblclick");
}
};
var $btn = $("#btn");
bindEvent($btn, events, "mydata", $btn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">MYBtn</button>
Note: As alert
is being invoked on click
event, dblclick
event is prevented, use console.log
instead of alert
and test!
Upvotes: 3
Reputation: 1686
Try this:
var eventBinder = function(obj, events) {
$.each(events, function(key, value) {
obj.on(key, function(e) {
events[key]();
});
});
}
var eventsData = {
click: function(e) {
console.log("click");
},
dblclick: function(e) {
console.log("dblclick");
}
};
eventBinder($("#btn"), eventsData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">MYBtn</button>
Upvotes: 1
Reputation: 8496
Both event always contradict but you can achiev this by counter number of clicks between small time interval.
//I hava this tool function to bind event
var bindEvent = function($dom,events,data,_this){
$dom.on(events);
};
var dblckickinterval = 500, clicks = 0, timer = null;
//and use like this
var events = {
click:function(e){
clicks++; //count clicks
if(clicks === 1) {
timer = setTimeout(function() {
alert("click"); //perform single-click action
clicks = 0; //after action performed, reset counter
}, dblckickinterval);
} else {
clearTimeout(timer); //prevent single-click action
alert("dblclick"); //perform double-click action
clicks = 0; //after action performed, reset counter
}
},
dblclick:function(e){
e.preventDefault();
}
};
var $btn = $("#btn");
bindEvent($btn,events,"mydata",$btn);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">MYBtn</button>
Upvotes: 2