Doug Fir
Doug Fir

Reputation: 21212

How do I pass additional parameters into an event

I have an array of clickable links "btns"

for ( var i=0; i<btns.length; i++ ) {      
        btns[i].addEventListener('click', eventData, false); 

eventData function is here:

function eventData(e) {
  dataLayer.push({
      'event': 'home_cta',
      'iteration': i, // HERE. I WANT TO ADD WHICH ELEMENT INDEX WITHIN THE FOR LOOP HERE
      'gtm.element': e.target,
      'gtm.elementClasses': e.target.className || '',
      'gtm.elementId': e.target.id || '',
      'gtm.elementTarget': e.target.target || '',
      'gtm.elementUrl': e.target.href || e.target.action || '',
      'gtm.originalEvent': e
    });

I have two questions:

  1. How do I pass anything into eventData on each iteration? For example, if var somevar = "bla", how would I pass that to eventData within my for loop?
  2. I would like to pass the iteration number into eventData. I have highlighted this in the 'iteration' property. So I'd like to end up with a number between 1 and 6 for each iteration (Because variable "btns" has length 6). How would I do that?

Upvotes: 1

Views: 51

Answers (2)

tckmn
tckmn

Reputation: 59273

This would involve an IIFE (immediately invoked function expression):

for (var i = 0; i < btns.length; i++) {
    (function(somevar, i) {
        btns[i].addEventListener('click', function(e) {
            eventData(e, somevar, i);
        }, false);
    })(somevar, i);
}

addEventListener passes one argument and one argument only to its callback, so you have to "manually" call your eventData function.

(Note that without the (function() { ... })(), each of the event listeners would have btns.length passed to them as the value for i.)

To explain the IIFE a bit more, here's what you're basically doing:

var f = function(somevar, i) {
    // ...
};
f(somevar, i);

That is, you're creating a function and immediately invoking it (hence the name). Again, this is done so that the value of i (and somevar if it changes) are kept the same for the appropriate iteration.

Upvotes: 4

Andreas
Andreas

Reputation: 21881

You could also use .bind() to "fixate" the first parameter of the bound function to the current index.

for (var i=0; i<btns.length; i++ ) {
    btns[i].addEventListener('click',
               // <this> in the function will be the clicked button (as usual)
               // but the first passed parameter would be the current iteration step <i>
               eventData.bind(btns[i], i),
               false);
}


function eventData(iteration, e) {
    //...
    'iteration': iteration,
}

fiddle

Upvotes: 0

Related Questions