Reputation: 44195
I have values I would like to keep in memory when certain events fire, like when a user is dragging and I want to save the element index. The value is needed when another event might fire. I don't know if it will ever fire.
I am using global variables to keep these values around. It seems there are better ways to do this like putting these values in an object with a namespace. Benefits? Any other suggestions?
Upvotes: 2
Views: 1341
Reputation: 92314
An alternative to using Function.bind (sometimes known as curry): You can control the scope of your shared variable. Here's some jQuery pseudo-code demonstrating it. Shared is accessible to those two handlers and nobody else.
$(function(){
var shared = {a:1, b:2};
$('#id-1').click(function() {
alert(shared.a);
});
$('#id-2').click(function() {
alert(shared.b);
});
});
If you're writing jQuery procedural code, the closure approach is much simpler. Since most everything I write is an object, I'd rather not get into too many levels of inner closures, so I prefer to setup a handler with binding/currying (like Martin's example) if a handler needs access to shared variables.
Upvotes: 0
Reputation: 26183
My alltime favorite is currying variables into event handlers. Curry is a function prototype and when called on a function it will return a version of the function with preset arguments:
Function.prototype.curry = function curry() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function curryed() {
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
};
};
node.addEventListener('mousedown', handler.curry(var1,var2,etc));
Upvotes: 4
Reputation: 6208
I like davin's solution, but here is an alternative if that doesn't suit you. You can create a closure around the event handler like so:
var data = { x: 1, y: 2 };
var handler = function() {
console.log(data);
}
if (node.addEventListener) {
node.addEventListener('mousedown', handler, false);
} else {
node.attachEvent('onmousedown', handler);
}
Upvotes: 1
Reputation: 45555
You could bind the data to a parent element that is a relevant container for each value. So for example, say you have a #dragAndDropContainer, in which there are many drag and droppable items, then as soon as a drag event fires (i.e. a drag begins), you could (in jQuery), execute:
$('#dragAndDropContainer').data('lastDragged', $(this).attr('id'));
And then just query $('#dragAndDropContainer').data('lastDragged')
every time you need to.
Upvotes: 3