0

I work on a site that recently changed, I track certain clicks on the site through GTM and push it into the dataLayer for Google Analytics.

With the changes to the site I can't use jQuery any more so I'm having to change the following jQuery to Javascript, but I just can't get it to work. The script used to collect the h3 text within the div class 'grid_4' when the div was clicked on. The whole structure has changed now, but the old jQuery one looked like this;

<script>
var h3Tile = $("div[class*='grid_4'] a").find('h3').text(); 
$("div[class*='grid_4'] a").click(function() {
  dataLayer.push({
    'h3Value' : h3Tile, 
    'event' : 'tileClick'
  });
});
</script>

The js I have so far is;

<script>
var outerElement = document.getElementsByClassName('ContentTeaser');
var childElems = outerElement.getElementsByTagName('h1').innerHTML;

var myFunction = function() {
  dataLayer.push({
    'h1Value' : childElems, 
    'event' : 'tileClick'
  });
};


for(var i=0;i<childElems.length;i++)
   childElems[i].addEventListener('click', myFunction(), false);

</script>

The only problem is that GTM refuses to accept this, saying;

'Uncaught TypeError: outerElement.getElementsByTagName is not a function'

Which I understand is related to the fact that I am creating an array rather than selecting an individual element, but I was hoping my for loop would handle this? or am I mistaken?

Thank you for any help anyone can offer.

Matt

1
  • getElementsByClassName returns a list of nodes, so you have to access one of them specifically, before you can then call another getFoo method on it. Commented Dec 2, 2015 at 12:36

1 Answer 1

1

getElementsByTagName is a method found on HTML Elements.

It and (more to the point) getElementsByClassName return an (array-like) HTML Collection, not a single HTML element.

You need to loop over outerElement and call getElementsByTagName on each element in turn instead of trying to call it on the collection itself.

Which I understand is related to the fact that I am creating an array rather than selecting an individual element, but I was hoping my for loop would handle this?

You have two collections. You are looping over the second one, but are trying to treat the first one as a single element.


It would probably be easier to simply use query selector instead:

var childElems = document.querySelectorAll(".ContentTeaser h1");

You then have a couple more problems:

for(var i=0;i<childElems.length;i++)

Since childElems is the value of innerHTML, it is undefined (if you'd called it on an element instead of an html collection then it would be a string instead) so that will throw an error.

Don't use innerHTML (which I already fixed in the query selector example).

childElems[i].addEventListener('click', myFunction(), false);

You are calling myFunction immediately and trying to assign its return value (undefined) as an event handler. Remove the ().

Sign up to request clarification or add additional context in comments.

2 Comments

Hi Quentin, thank you very much for such a detailed response! It does now work for all clicks on the h1. I was wondering as there are other areas within .ContentTeaser that are not the h1, that are still part of the link (a couple of span tags). Is it possible to still pull the h1 when they are clicked as well?
Hi Quentin, sorry to bother you, but I don't suppose you know if it's possible to pull the h1 when the code is something similar to the below; <a> <span>text</span><h1>text</h1></a> and some users are clicking on the span tag text?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.