Ok, I've been hitting my head for over a week now and I can't take it anymore.
My goal here is to randomly replace the HREF of a specific URL on any given page.
For example: https://example.com/offer/free-pizza/
There are versions of my URL that contain query string parameters, i.e. https://example.com/offer/free-pizza/?sliceapp that I want to ignore, that's why I explicitly use regex to call out the quotation marks for my specific URL in this line:
str.replace(/"https:\/\/example\.com\/offer\/free-pizza\/"/g
I'm deploying the code below using a Custom HTML tag in Google Tag Manager. Unfortunately, the links do not contain IDs, so I can't specifically call upon those, so I'm looking at everything contained within the body of the page, in other words, , which is the body of each page I'm working with. Everything works exactly as expected with the code below, except that the lazy-loaded images on the page do not appear.
<script>
function myfunction(){
var str = document.getElementById("main").innerHTML;
var res = str.replace(/"https:\/\/example\.com\/offer\/free-pizza\/"/g, function() {
return ['https://example.com/somewhere-else/', 'https://example.com/offer/free-pizza/'][Math.floor(Math.random() * 2)]
return Math.floor(Math.random() * (max - min + 1)) + min;
});
document.getElementById("main").innerHTML = res;
}
</script>
From my troubleshooting, I know the issue has something to do with using innerHTML to return the entire . Something clearly doesn't work there with the images and the returned HTML. So I set off to instead just look at the individual URLs on the page, not the whole section, so I could bypass the image issue altogether.
I must have written tens of dozens of variations at this point to try and accomplish this, but nothing seems to work.
var els = document.querySelectorAll("a[href^='https://example.com/offer/']");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
el = el.replace(/"https:\/\/example\.com\/offer\/free-pizza\/"/g, function() {
return ['https://example.com/somewhere-else/', 'https://example.com/offer/free-pizza/'][Math.floor(Math.random() * 2)]
return Math.floor(Math.random() * (max - min + 1)) + min;
})};
</script>
I'm hoping that someone much smarter than me can see my obvious flaws and point me in the direction of how I can write this in a much more effective way, given the context and my goal.
Thank you.
The problem with replacing the whole document's innerHTML
is, that you might remove (and replace) DOM nodes that have attached event listeners to them, which makes them void. I guess the lazy loading mechanism makes use of this.
Thus, instead of replacing the whole document's innerHTML
, you could just iterate over the anchor tags and replace the href
property:
document
.querySelectorAll("a[href^='https://example.com/offer/']")
.forEach(function (el) {
el.href = el.href.replace(/https\:\/\/example\.com\/offer\//g, replaceFn);
});
function replaceFn() {
return [
'https://example.com/somewhere-else/',
'https://example.com/offer/free-pizza/'
][Math.floor(Math.random() * 2)];
}