Inserted iframes are not cleared from the DOM with GTM - google-analytics

I have a GTM script implemented in my Angular application (SPA - Single Page Application).
When I change the page, a Page-View event is triggered via: window.dataLayer.push(obj)
obj represents the whole object.
On GTM side, I have 2 triggers as a result:
Insert to the DOM a Custom HTML element (a script element) that triggers another dataLayer.push with a simple object that indicates the new page view and the previous referer.
Insert to the DOM an iframe of type DoubleClick Floodlight to track certain behaviors for a short lifespan.
Now, to my understanding, these events should have been inserted to the DOM once and get cleared after that.
As it seems, for every page view that a user creates while navigating in the app, linearly, 2 elements are appended to the DOM (scropt element + iframe).
This behavior causes a tremendous amount of js heap size. I see a great memory leak in the Memory tab in chrome DevTools.
Of course, dataLayer keeps track of events and once it gets to 300 events it pops the oldest event, etc...
I would like to know is this is an expected behavior by design and it's just me that is missing a key component in GTM.
Am I supposed to create a cleanup tag to trigger after all of my elements are inserted to the DOM?
Or even better, try to track it and remove it from within my application?
I feel like I did not truly understand my problem so I can only hope you have a clue what I'm aiming to explain here.
Thanks ahead.
I did not try anything.
All I did was to read stackoverflow questions and answers, combined with a lot of articles, videos, dry documentation.
I do have a few leads as to what to try and tackle but I prefer the community to guide me through their experience if possible.

Related

FullCalendar: is there still a viewRender event hook?

I need something like the viewRender event in order to persist the user's state. I'm building a UI where users will frequently jump in and out of the calendar, so preserving their view/range is essential for a pleasant experience. Does this exist in v5? The last mention I can find of it is from v3.
The only workaround I can think of right now is a direct click handler on every view control element, or a very heavy-handed MutationObserver. This is a React app so either one is going to be super awkward.
Thank you!
Edit 2021-02-11:
I looked at the available view render hooks but none of them address my problem. What I need is an event that will fire whenever the view state changes, including clicking between weeks/months/etc., so that I can persist the date range the user most recently viewed as well as the view they had selected.
viewDidMount is the closest to what I need, but it does not fire when the date range changes.
Edit 2021-05-26:
Another problem with using viewDidMount is that using it to enact side-effects is a bit overeager. The hook gets called whether or not the user has actually done anything, and the default view always gets passed as view inside the View Object. So there's no way to tell whether this mount event contains data I should persist or not.

How can I make GTM tags fire "once per page" on a single page application?

I have a single page web app with a third party marketing tool I need to track. The tool implements a form.
What I need to know is:
How many people started filling in the form on a certain page type, i. e. first-clicked any of the fields (once per page)
All of the fields share the same class (at least partly). So I created a trigger that fires on
"[click classes] starts with [classname part]" AND
"[page url] contains [pagetype]".
This trigger is used for an event tag A with the "tag firing options: once per page", so that I do not get all of the element clicks, but only the relevant amount of starts which is per page. *
How many people successfully submit a form (once per page)
This was a little more tricky, since "successfully" means that I am not interested in simple button clicks, since those could also end in error messages if someone missed filling in a required field. Also, I do not get a success page, but a success message. The div this message appears in is always there, it is just not filled until submission. I solved this by creating a custom variable defining that element and an "element visibility trigger" that fires on
"[page url] contains [pagetype]" AND
"[custom variable]" equals [success message]"
+ DOM change observance.
This trigger is used for event tag B with the "tag firing options: once per page". This is necessary, since the marketing tool allows multiple successful submits of the very same form (please don't ask). Therefore, I need to restrict this to once per page as well. *
*) Now here's my struggle: This setup would be working fine for a multi page application with a standard page view tracking. However, I need to have my standard page view trigger to fire at history event changes, and this crashes my setup. I don't know how to restrict the two new event tags A+B for firing "once per page" if I don't have actual page views.
I cannot imagine that I am the only person who needs to solve this case. However, either everyone else just knows how to or I am not searching well enough - I don't find anything on this matter.
Does anyone have any idea on how to solve this?
Any slightest hint would be very much appreciated!
Thanks in advance!

Implementing GTM dataLayer

Need some advice in relation to giving our developers the code for the dataLayer that is to be used along with the GTM code.
If the dataLayer is to be on every page along with the container tag code, how do i define all variables for many events across the domain?
dataLayer = [];
I've read that using macros is the best way going forward, which should mean less time dealing with the developers in the future. I'm not a coder so i'm struggling to understand what code to give. Struggling with the current lack of documentation for non-developers.
The website is a non-ecommerce site but we track many events as micro-conversions.
Ninjasys,
your code is correct :-). You have successfully implemented GTM data layer (it should be before GTM tag itself in the source code of your webpage).
The only thing you need to do now is to fill it. You can either specify its items when the page loads (if there is a need for that), or you can push updates to it when a user does something (like clicks on the button / selects a drop-down value).
Using onclick attributes is the easiest way -- simply add:
onclick="dataLayer.push({'event': 'EventFire-TopMenu',
'EventCategory': 'Navigation', 'EventAction': 'Menu', 'EventLabel':
'QuickCheck'});"
With this code, you are telling GTM to track an event. Setup 3 macros that will retrieve the values from data layer (EventCategory, EventAction and EventLabel) and then set a rule to trigger a Google Analytics Event Tag with the condition being event equals EventFire-TopMenu.
Keep in mind that you can pick any names you want, I just copied the example above from one of my webpages. I would also suggest reading few articles about event listeners that GTM introduced few months back, it makes your life a lot easier.
But I hope this simple example will get you started.

Caching the whole page so it looks the same when using the back button

I am talking about list pages in which I am using many filters. Actually these filters are in a user control and are ajaxified. Can I cache the state of the page after applying say 4-5 filters, so that if I move to another page after applying these filters and then return to the original page by pressing back button I will see the same filtered state of the page? I am not changing the url after applying any filters. Can this be done by output caching?
What you're asking for really has nothing to do with caching. Well, it does, but not the kind of caching I think you're talking about :-) FireFox has what is known as the bfcache, which stores the state of a page's DOM as it was when you navigated away from that page. This is used so that when you return to the page, it will look the same as it did when you were there last.
However, certain events cause the bfcache to not be used. For example, this question details how the unload event affects things. If I were you, I would revisit the "I am not changing the url after applying any filters" statement -- I would reccomend storing the state of the page in a docuemnt.location.hash. Here's a question which details that concept

triggering javascript events using asp.net

I'm writing an asp.net web app. and i've hit a bit of a brick wall.
basically i have 2 pages, the main page with a text box in and a popup that contains a treeview.
My problem is this. when i select a treeview item i want the program to perform some database transactions using asp.net and then pass the value retrieved from the database into a javascript function that passes the data back from the popup page to the parent page. My problem is that i cannot find any way of calling a javascript function from asp.net. I've tried assigning attributes to controls on page load, but this does not work as when the page loads the data has not been retrieved from the database.
Have a look at the ClientScriptManager class. You can register scripts from code-behind that will run when the HTML page loads. Those scripts can call other javascript functions on the page.
There are many tutorials and examples on the Web. Here's one I found that may help but there are many more.
How to use the client script manager
You hit the nail on the head when you said "I've tried assigning attributes to controls on page load, but this does not work as when the page loads the data has not been retrieved from the database." You just need to discover when you're pulling the data from the database, and then assign the values after that. Without looking at your code, there's no way to know for sure, but Page_PreRender is probably a good bet to assign your values...it's probably after you're pulling information from the db...it's pretty much the last place that you can make things happen before the html is generated for the client.
You can invoke a function resided in the Main Page and call that function in the Main Page from the Child Page which is your pop up window.
Please refer to these links for references
http://chiragrdarji.wordpress.com/2007/03/10/call-parent-windows-javascript-function-from-child-window-or-passing-data-from-child-window-to-parent-window-in-javascript/
http://www.webmasterworld.com/forum91/2957.htm
http://hspinfo.wordpress.com/2008/01/12/call-parent-windows-javascript-function-from-child-window/
This one helps with retrieving popups from values using javascript
http://www.eggheadcafe.com/articles/20060117.asp
This one shows how to fire a postback using javascript, and manage it in the codebehind.
http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx
If you put them together, and use Control.ClientID to find the actual "html name" of your asp.net controls, you'll be able to set that up in no time.
Might not be the prettiest way to do it in town, and incidentally make little baby Jesus cry, but anyway, it works.
[edit]Oh. I just saw that it seems I answered the question the other way around, or "how to trigger codebehind from Javascript". I think the method I suggest may help you, if you use it right.
The javascript of the popup should pass the information to the parent window, and the parent window function should call a postback when it receives the information.
The javascript of the popup window should be only registered on a postback with the correct information retrieved, so that when the postback occurs on the popup because of the selection of the right information, the window closes and passes the information to the parent page.
The parent page, triggering postback, does the thingies you need it to, and the app resumes "normally" from there on, doing whatever you need it to, outside of the popup page.

Resources