#GTMTips: Get Position Index of Visible Element

Use a Custom JavaScript variable in Google Tag Manager to get the position of the element that became visible, when using the Element Visibility trigger.

It’s time for a very simple #GTMTips article (I know, I always write that these are simple tips, but then they escalate into complex behemoths). Today, we’ll cover a nifty trick you can use with the Element Visibility trigger in Google Tag Manager. This tip was inspired by a question from Eugen Potlog in the Google Tag Manager Facebook group.

The use case is that you have an Element Visibility trigger firing for a number of elements all sharing the same CSS selector. In the image below, I want the visibility trigger to fire when any <h2> header element becomes visibile on the screen. However, I also want to know which one of all those headers caused the trigger to fire. In other words, I want the position of the header; If it’s the 5th header from the top, I want to get the number 5 to use in my tags. If it’s the first header, I want it to return 1.

This is quite easy to do with a Custom JavaScript variable, and below I’ll show you how.

Tip 84: Get the position index of the visible element

Here’s what the Custom JavaScript variable should look like:

function() {
  var list = document.querySelectorAll('h2'), // Make sure this CSS selector matches the one in the trigger
      el   = {{Click Element}};
  return [].indexOf.call(list, el) + 1;
}

This makes use of something you might not have thought of before, namely the fact that the built-in variable {{Click Element}} returns the element that caused the Element Visibility trigger to fire. It’s a multi-purpose variable in that sense.

The script first creates a list of all the possible elements the Element Visibility trigger can fire for, so it’s important that the selector argument of document.querySelectorAll(selector) matches the one you use in the Element Visibility trigger. Once the list is created, indexOf() is used against a native array object (because the list returned by querySelectorAll doesn’t have the .indexOf() method), and it checks if the list contains the element that fired the trigger.

If the list does contain it, the element’s position is returned as a positive integer, so the first element on the page would be 1, the second would be 2 and so on. If the element does not match against the list of elements in the variable list, position 0 is returned. This means you have misconfigured the selector(s).

This was a simple tip, undoubtedly, but I hope it’s useful to some of you!