Categories
Web analytics

Custom timer measuring the actual time spent on the page depending on the length of the content. GTM + GA

What did I want?

Measure the time on the content page so I can say that users have really read the content. Of course, this is a script in Google tag manager.

Required features:

  • Start measuring only on a loaded page (DOM ready) when the user really sees the page.
  • Measure the real time the user sees the page. This results in the use of document.visibilityState and the visibilitychange listener.
  • I wanted to change the length of time according to the length of the text. I wanted to use it to define a well-read article.

GTM trigger for HTML script.

Triggers only when the user has loaded the page content and sees it.

.*Check all events  + Use regex matchingSince I have enough GTM events in the page, all I need is this rule. For some sites, you will need to add a listener to change the visibility .
Rule:
gtm.dom equals true(The variable gtm.dom is a dataLayer variable named “gtm.dom”)
js.document.visibilityState equals visibleIt is a javascript variable document.visibilityStatesupport 96.16% ) with settings Convert undefined to notsupport . For other browsers, you can make a GTM triger Timer 30sec and name it anyway and set the condition in reverse, it will run at notsupport.

How does it work?

It launches only on the page that is loaded at the DOM level and at the same time the page is in the focus window (trigger). The window is not displayed in the next tab of the browser and the user really sees it.

At the beginning is the setting:

var TimerDynamicSetting = {
      count: 0, // Kolikrát byl časovač spuštěn
      repeat: 2,  // Kolikrát se časovač má opakovat
      active: 1, // Je aktuálně časovač aktivní?
      customtime: 10000 // Jaká je minimální hodnota časovače v milisekundách.
    }
The following is the code for measuring the number of words and calculating the time required to read the content

This works if the content page is a Variable {{dl.pagePostType2}} contain "single-". I got this variable from the WordPress plugin on GTM which I really like DuracellTomi’s Google Tag Manager for WordPress and I recommend it. This condition can be done in any other way, or you can delete this content and set the time in the timer to fixed. Otherwise, it is calculated here that a fast reader can handle 228 words per minute, and I will want him to read at least a quarter of the content at this speed, adding to the minimum time spent on the page.

document.querySelector("#main") It is a general selector of the main content for wordpress. In general, this is a place for creativity.

  try {
    if ({{dl.pagePostType2}}.includes("single-")) {
      TimerDynamicSetting.customtime = TimerDynamicSetting.customtime + Math.floor((document.querySelector("#main")
.innerText.replace(/(^\s*)|(\s*$)/gi, "")
.replace(/[ ]{2,}/gi, " ").replace(/\n /, "\n")
.split(' ').length / 228) * 60 * 0.25) * 1000;
    }
  } catch (e) {;};

Then the code follows the code for setting and starting the timer with the pause and resume functions.
Then the code monitoring changes is visibilityState.
Finally, registration of javascript functions waiting for browser events.

The entire timer code measuring the time on the visible page then looks like this:
<script>var TimerDynamicSetting = {
      count: 0,
      repeat: 2, 
      active: 1, // Is timmer active?
      customtime: 10000 // Minimum timer time in seconds
    },
    TimerDynamicvar;

 // Setting time according to content length
 // dl.pagePostType2 - WordPress variable from 
  try {
    if ({{dl.pagePostType2}}.includes("single-")) {
      TimerDynamicSetting.customtime = TimerDynamicSetting.customtime + Math.floor((document.querySelector("#main")
.innerText.replace(/(^\s*)|(\s*$)/gi, "")
.replace(/[ ]{2,}/gi, " ").replace(/\n /, "\n")
.split(' ').length / 228) * 60 * 0.25) * 1000;
    }
  } catch (e) {;};

  //Timer with pause and resume function
  function TimerDynamic(d, e) {
    var a, b, c = e;
    this.pause = function() {
      window.clearTimeout(a);
      c -= new Date - b;
    };
    this.resume = function() {
      b = new Date;
      window.clearTimeout(a);
      a = window.setTimeout(d, c);
    };
    this.resume();
  }

  function TimerDynamicStart() {
    TimerDynamicSetting.active = 1;
    TimerDynamicvar = new TimerDynamic(function() {
      TimerDynamicSetting.count += 1;
      TimerDynamicSetting.active = 0;
      dataLayer.push({
        event: "TimerDynamic",
        "TimerDynamic.count": TimerDynamicSetting.count,
        "TimerDynamic.repeat": TimerDynamicSetting.repeat,
        "TimerDynamic.customtime": TimerDynamicSetting.customtime * 0.001
      });
      clearTimeout(TimerDynamicvar);
      TimerDynamicSetting.count < TimerDynamicSetting.repeat && TimerDynamicStart();
    }, TimerDynamicSetting.customtime);
  }

  function handleVisibilityChangeForTimmer() {
    "hidden" == document.visibilityState ? 1 === TimerDynamicSetting.active && TimerDynamicvar.pause() : (dataLayer.push({
      event: "visibilityChange.on"
    }), 1 === TimerDynamicSetting.active && TimerDynamicvar.resume());
  }
  TimerDynamicStart();
  document.addEventListener("visibilitychange", handleVisibilityChangeForTimmer, !1);</script>

This code is inserted into GTM tag type of HTML , it is set to 1 run per page, and set trigger.

And this is a compressed version of a previous script
var TimerDynamicSetting = {count:0, repeat:2, active:1, customtime:10000}, TimerDynamicvar;
try {{{dl.pagePostType2}}.includes("single-") && (TimerDynamicSetting.customtime += 1000 * Math.floor(document.querySelector("#main").innerText.replace(/(^\s*)|(\s*$)/gi, "").replace(/[ ]{2,}/gi, " ").replace(/\n /, "\n").split(" ").length / 228 * 15));} catch (b) {}
function dynamictimer(f){var a,b,c=TimerDynamicSetting.customtime;this.pause=function(){window.clearTimeout(a);c-=new Date-b};this.resume=function(){b=new Date;window.clearTimeout(a);a=window.setTimeout(f,c)};this.resume()}
function DynamicTimerStart(){TimerDynamicSetting.active=1;TimerDynamicvar=new dynamictimer(function(){TimerDynamicSetting.count+=1;TimerDynamicSetting.active=0;dataLayer.push({event:"TimerDynamic","TimerDynamic.count":TimerDynamicSetting.count,"TimerDynamic.repeat":TimerDynamicSetting.repeat,"TimerDynamic.customtime":.001*TimerDynamicSetting.customtime});clearTimeout(TimerDynamicvar);TimerDynamicSetting.count<TimerDynamicSetting.repeat&&DynamicTimerStart()})}DynamicTimerStart();
document.addEventListener("visibilitychange",function(){"hidden"==document.visibilityState?1===TimerDynamicSetting.active&&TimerDynamicvar.pause():(dataLayer.push({event:"visibilityChange.on"}),1===TimerDynamicSetting.active&&TimerDynamicvar.resume())},!1);

Where do I use it?

If the user is on an article and spends time there defined enough to move within the noidle time and see the end of the page, then I declare that the user has read the content well enough and send the transaction with ecom article definition to Google analytics.

.