Skip to content
Advertisement

Copying JS events from one element to another

I’m attempting to copy events from one element, to another using pure JS (i.e. not JQuery).

The bug I’m hitting, is when there’s multiple events, the last event is used for both.

Bit hard to explain, please refer to my jsbin example, I want to copy the mousedown and mouseup events from #foo to #bar. The bug is, the mouseup event is fired for both mouseup and mousedown on the #bar element.

Here’s the code snippet I’m currently working with, to copy events.

copyEvents(fromEl, toEl, ['onmousedown', 'onmouseup']);

function copyEvents(fromEl, toEl, events){
  for (var i = 0; i < events.length; i++){
    var event = events[i];
    var func = fromEl[events[i]];
    if(func){
      if (console){ console.log('Copying event - ' + event + ' = ' + func); }
      toEl[event] = function(evt){ func.call(this); };
    }
  }
}

Advertisement

Answer

The JSHint warning on your example should give you a tip on what’s happening:

Don’t make functions within a loop

The root of your problem is the JavaScript infamous loop issue.

If you loop with forEach you avoid this issue altogether as you introduce a new scope:

function copyEvents(fromEl, toEl, events){
  events.forEach(function(ev, i) {
    var func = fromEl[ev];
    if(func){
      toEl[ev] = function(evt){ func.call(this); };
    }
  });
}

But you don’t need an anonymous function. You can keep your current code if you simply assign the function directly:

toEl[event] = func;

That will work because this is dynamic, resolved when the function is called.

Demo: http://jsbin.com/wowap/1/edit

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement