Tony_Henrich
Tony_Henrich

Reputation: 44195

Clean way to pass parameters between JavaScript events?

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

Answers (4)

Ruan Mendes
Ruan Mendes

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

Martin Jespersen
Martin Jespersen

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

Hemlock
Hemlock

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

davin
davin

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

Related Questions