Guida Avanzata

Guida Avanzata: tracciare lo Scrolling di una pagina con Google Tag Manager

[AGGIORNATO 11 MARZO 2020]

PREMESSA

Da quasi due anni Google Tag Manager ha realizzato un attivatore nativo che permette di gestire lo scrolling. Ecco la guida: www.tagmanageritalia.it/guida-base-attivatore-profondita-scorrimento-google-tag-manager/

Di seguito la soluzione che adottavo prima degli attivatori nativi di scrolling.

Ormai abbiamo capito che grazie a Google Tag Manager siamo in grado di tracciare tutti i comportamenti degli utenti in un sito internet, anche i più improbabili o curiosi. Uno di questi è sicuramente l’evento Scroll del mouse.

Tracciare in quali pagine gli utenti “scrollano” di più, ed addirittura sapere quanto hanno scrollato, può essere molto interessante ed utile per capire la qualità dei contenuti delle pagine e la loro propensione a creare interesse negli utenti.

Ecco come installare il monitoraggio dello Scrolling nelle pagine, con Google Tag Manager naturalmente.

PS: Lo script di tracciamento si basa sul framework JavaScript di jQuery, quindi dovresti installarlo nel sito (se hai WordPress è già incluso 😛 ).

Step 1 – Crea il Tag Scroll Event

Come prima cosa crea un nuovo Tag per attivare l’evento Scroll. In Google Tag Manager seleziona:

  • Tag > Nuovo > Configurazione tag.
  • Tipo di tag: Tag HTML personalizzato.
  • Adesso incolla il seguente codice (oppure vai in fondo all’articolo, troverai il link):

Attenzione: alla fine dello script devi inserire il codice: jQuery(function() { jQuery.scrollDepth(); });

<script>
;(function ( $, window, document, undefined ) {

"use strict";

var defaults = {
minHeight: 0,
elements: [],
percentage: true,
userTiming: true,
pixelDepth: true,
nonInteraction: true,
gaGlobal: false,
gtmOverride: false
};

var $window = $(window),
cache = [],
scrollEventBound = false,
lastPixelDepth = 0,
universalGA,
classicGA,
gaGlobal,
standardEventHandler;

$.scrollDepth = function(options) {

var startTime = +new Date;

options = $.extend({}, defaults, options);

// Return early if document height is too small
if ( $(document).height() < options.minHeight ) {
return;
}

if (options.gaGlobal) {
universalGA = true;
gaGlobal = options.gaGlobal;
} else if (typeof ga === "function") {
universalGA = true;
gaGlobal = 'ga';
} else if (typeof __gaTracker === "function") {
universalGA = true;
gaGlobal = '__gaTracker';
}

if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
classicGA = true;
}

if (typeof options.eventHandler === "function") {
standardEventHandler = options.eventHandler;
} else if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function" && !options.gtmOverride) {

standardEventHandler = function(data) {
dataLayer.push(data);
};
}

function sendEvent(action, label, scrollDistance, timing) {

if (standardEventHandler) {

standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventValue': 1, 'eventNonInteraction': options.nonInteraction});

if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
lastPixelDepth = scrollDistance;
standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': 'Pixel Depth', 'eventLabel': rounded(scrollDistance), 'eventValue': 1, 'eventNonInteraction': options.nonInteraction});
}

if (options.userTiming && arguments.length > 3) {
standardEventHandler({'event': 'ScrollTiming', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventTiming': timing});
}

} else {

if (universalGA) {

window[gaGlobal]('send', 'event', 'Scroll Depth', action, label, 1, {'nonInteraction': options.nonInteraction});

if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
lastPixelDepth = scrollDistance;
window[gaGlobal]('send', 'event', 'Scroll Depth', 'Pixel Depth', rounded(scrollDistance), 1, {'nonInteraction': options.nonInteraction});
}

if (options.userTiming && arguments.length > 3) {
window[gaGlobal]('send', 'timing', 'Scroll Depth', action, timing, label);
}

}

if (classicGA) {

_gaq.push(['_trackEvent', 'Scroll Depth', action, label, 1, options.nonInteraction]);

if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
lastPixelDepth = scrollDistance;
_gaq.push(['_trackEvent', 'Scroll Depth', 'Pixel Depth', rounded(scrollDistance), 1, options.nonInteraction]);
}

if (options.userTiming && arguments.length > 3) {
_gaq.push(['_trackTiming', 'Scroll Depth', action, timing, label, 100]);
}

}

}

}

function calculateMarks(docHeight) {
return {
'25%' : parseInt(docHeight * 0.25, 10),
'50%' : parseInt(docHeight * 0.50, 10),
'75%' : parseInt(docHeight * 0.75, 10),
// Cushion to trigger 100% event in iOS
'100%': docHeight - 5
};
}

function checkMarks(marks, scrollDistance, timing) {
// Check each active mark
$.each(marks, function(key, val) {
if ( $.inArray(key, cache) === -1 && scrollDistance >= val ) {
sendEvent('Percentage', key, scrollDistance, timing);
cache.push(key);
}
});
}

function checkElements(elements, scrollDistance, timing) {
$.each(elements, function(index, elem) {
if ( $.inArray(elem, cache) === -1 && $(elem).length ) {
if ( scrollDistance >= $(elem).offset().top ) {
sendEvent('Elements', elem, scrollDistance, timing);
cache.push(elem);
}
}
});
}

function rounded(scrollDistance) {
// Returns String
return (Math.floor(scrollDistance/250) * 250).toString();
}

function init() {
bindScrollDepth();
}

// Reset Scroll Depth with the originally initialized options
$.scrollDepth.reset = function() {
cache = [];
lastPixelDepth = 0;
$window.off('scroll.scrollDepth');
bindScrollDepth();
};

// Add DOM elements to be tracked
$.scrollDepth.addElements = function(elems) {

if (typeof elems == "undefined" || !$.isArray(elems)) {
return;
}

$.merge(options.elements, elems);

// If scroll event has been unbound from window, rebind
if (!scrollEventBound) {
bindScrollDepth();
}

};

// Remove DOM elements currently tracked
$.scrollDepth.removeElements = function(elems) {

if (typeof elems == "undefined" || !$.isArray(elems)) {
return;
}

$.each(elems, function(index, elem) {

var inElementsArray = $.inArray(elem, options.elements);
var inCacheArray = $.inArray(elem, cache);

if (inElementsArray != -1) {
options.elements.splice(inElementsArray, 1);
}

if (inCacheArray != -1) {
cache.splice(inCacheArray, 1);
}

});

};

function throttle(func, wait) {
var context, args, result;
var timeout = null;
var previous = 0;
var later = function() {
previous = new Date;
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = new Date;
if (!previous) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
return result;
};
}

function bindScrollDepth() {

scrollEventBound = true;

$window.on('scroll.scrollDepth', throttle(function() {

var docHeight = $(document).height(),
winHeight = window.innerHeight ? window.innerHeight : $window.height(),
scrollDistance = $window.scrollTop() + winHeight,

// Recalculate percentage marks
marks = calculateMarks(docHeight),

// Timing
timing = +new Date - startTime;

// If all marks already hit, unbind scroll event
if (cache.length >= options.elements.length + (options.percentage ? 4:0)) {
$window.off('scroll.scrollDepth');
scrollEventBound = false;
return;
}

// Check specified DOM elements
if (options.elements) {
checkElements(options.elements, scrollDistance, timing);
}

// Check standard marks
if (options.percentage) {
checkMarks(marks, scrollDistance, timing);
}
}, 500));

}

init();

};

})( jQuery, window, document );
jQuery(function() { jQuery.scrollDepth(); });

</script>
  • Nello step successivo, scegli dove attivare questo Tag. Io ho scelto di attivarlo in tutte le pagine: All Pages / Visualizzazione di Pagina.
  • Salva il Tag nominandolo prima “Scroll Event”.

Step 2 – Visualizza in anteprima

Attiva ora la modalità Visualizzazione in Anteprima e vai nel tuo sito web.
Scrollando, vedrai comparire dei nuovi eventi sulla colonna sinistra della finestra dell’Anteprima. Questi nuovi eventi sono “ScrollDistance” e “ScrollTiming”.

Come puoi vedere, nella scheda “Data Layer”, sono presenti una serie di Variabili che includono delle informazioni riguardanti lo scroll. Andremo ora ad estrarre queste Variabili.

Step 3 – Crea le Variabili

  • Torna in Google Tag Manager, vai nella sezione Variabili > Nuova> Configurazione variabili.
  • Tipo di variabile: Variabile di livello dati.
  • Nome variabile di livello dati: eventCategory.
  • Versione livello dati: Versione 2.
  • Nomina la Variabile “eventCategory” e salvala.

Segui lo stesso procedimento per creare le variabili “eventAction” ed “eventLabel”.

Step 4 – Crea l’Attivatore

  • Vai su Attivatori, dal menu a sinistra di Google Tag Manager > Nuovo > Configurazione Attivatore.
  • Tipo di attivatore: Evento personalizzato.
  • Nome evento: ScrollDistance.
  • Attiva su: Tutti gli eventi personalizzati.
  • Nomina l’Attivatore “ScrollDistance Event”.
  • Salva.

“ScrollDistance” era appunto il nome dell’evento che abbiamo visto prima nella Visualizzazione in Anteprima.

Step 5 – Crea un nuovo Tag

Crea ora un nuovo Tag.

  • Tipo di tag: Universal Analytics.
  • Tipo di monitoraggio: Evento.
  • Categoria: {{eventCategory}}
  • Azione: {{eventAction}}
  • Etichetta: {{eventLabel}}
  • Hit da non interazione: False.
  • Adesso puoi inserire la variabile delle impostazioni di Google Analytics o in alternativa abilitare l’override e inserire in ID monitoraggio il tuo codice di monitoraggio di Analytics oppure la costante {{gaID}}, se l’hai creata.
  • Nell’ultima sezione Attivazione seleziona l’Attivatore “ScrollDistance Event” che hai creato allo step 4.
  • Salva il tag nominandolo “GA – Event – Scroll”.

Step 6 – Verifica il Tag

Ora è proprio tutto. Ma prima di pubblicare non ti resta che controllare il corretto funzionamento delle modifiche implementate.

Accedi nuovamente con la modalità Visualizzazione in Anteprima. Il Tag dovrebbe prima comparire fra i Tags Not Fire On This Page.

Se provi a scrollare la pagina, dovresti vedere passare il Tag fra i Tag Fired On This Page.

Se tutto funziona, torna su Google Tag Manager e pubblica il Tag con il tasto blu in alto a destra “Salva”.

Se andrai a visualizzare, ora, gli eventi in Google Analytics vedrai comparire anche questi relativi agli Scroll degli utenti potendo monitorare anche la percentuale di scrolling per ogni evento (25%, 50%, 75%, 100%).

Prova ad implementare questa funzionalità molto interessante, se dovessi riscontrare problemi scrivimi pure commentando qui sotto.

Buon Tag!

Fonte codice: https://github.com/robflaherty/jquery-scrolldepth/blob/fe381fa7eb7b9b5c1a638d6d9821ba605f442284/jquery.scrolldepth.js

Matteo Zambon

View Comments

  • Ciao Matteo, prima di tutto grazie per le guide sei eccezionale. Ho eseguito alla lettera quanto da te descritto ma non ricevo dati su analitycs, avrò commesso un errore in qualche passaggio a cui non riesco a risalire. Ho iniziato a seguirti secondo segnalazione di un mio carissimo amico che tu conosci di sicuro ma che non posso ovviamente menzionarti qui

  • Ciao matteo! guida utilissima ma l'evento per il page scroll dove posso vederlo nel dettaglio ? si può vedere anche in tempo reale?

  • Ciao Matteo, ti ho scritto prima chiedendoti informazioni per capire se esistesse una guida del genere e invece... eccola qua. WOW!

    Ho solo una domanda da porti. Ho impostato il tag e sembra che tutto funzioni benissimo. Volevo quindi chiederti: da dove posso vedere informazioni specifiche dell'evento in relazione alla pagina? Mi spiego meglio, se voglio controllare lo scrolling parziale o totale degli utenti in alcuni articoli del mio blog devo modificare l'attivatore inserendo solo le pagine che mi interessano oppure, selezionando tutte le pagine, c'è una sezione di analitics che mi fornisce il dato? Spero di essermi spiegato bene.. Grazie!

  • Ciao Matteo, ottima guida mi è tornata molto utile.

    Dopo l'implementazione mi sono reso conto che con queste impostazioni l'evento mi abbatteva il bounce-rate, allora ho cambiato l'impostazione in Hit da non interazione da False a True. Ora il bounce è tornato apposto ;)

    A presto e grazie per le info!

    • Ciao Giovanni, ora c'è un nuovo attivatore che gestisce in modo nativo lo scrolling ;)

      A presto!

  • Ciao Matteo.. mi stai salvando la vita :)
    Ho appena implementato ma ho un problema, ovvero quando faccio lo scroll in anteprima il tag mi resta sempre sotto "Tags Not Fired On This Event". Ho provato a fare il refresh della pagina ma niente.
    Mi sai dire perché?

    Grazie mille,

    Morgana

    • Ciao Morgana, dovevo valutare di diventare medico quella volta allora :D

      Battute a parte, hai verificato che venga creato l'evento ScrollTiming e ScrollDistance? Ti appare in anteprima nel debug?

  • Ciao Matteo, ottima la tua guida!
    Per quanto riguarda questo monitoraggio, solo a me dopo aver implementato tutto la frequenza di rimbalzo si è praticamente dimezzata?Puoi aiutarmi a capire quale può essere il problema? GRAZIE!

    • Ciao Eleonora, devi semplicemente verificare se hai messo Hit da non interazione: False nel Tag di Google Analytics :)

  • Ciao Matteo,
    Prima di tutto complimenti, le tue guide sono molto chiare ed efficaci.
    Solo una domanda, una volta che decido di implementare il tag su tutte le pagine, su Analytics, mi dirà precisamente su quale pagina gli utenti hanno fatto uno scroll del 25% ecc..?
    Ti ringrazio

  • ciao, ho lette in giro che c'e' un modo anche per tracciare lo scrolling in base a dei punti fissi della pagina, ad es. ancore inserite nella pagina stessa. hai qualche riferimento per questo caso?

    • Ciao Dario,
      prova a dare un occhio al sito dell'autore, mi sembra ci siano dei parametri configurabili: http://scrolldepth.parsnip.io/.
      E' anche probabile che esistano altri framework js più dettagliati su questa tua esigenza, ma al momento non saprei consigliarti esattamente. Nel caso lo trovassi fammelo sapere che aggiorno l'articolo inserendo la tua alternativa.

      A presto!

  • ciao, molto utile e appena implementato... sarebbe bello pero' avere qualche riferimento anche per creare un report che consenta la lettura dei dati... suggerimenti??

  • Ciao Matteo,
    grazie mille per la guida: da poco abbiamo creato una nuova pagina nel sito aziendale ed è abbastanza lunga, questa funzionalità ci servirà parecchio.
    La funzionalità è stata appena creata da me, quando potrò vedere l'evento in Analytics? 24-48 ore?
    Grazie ancora e a presto!

    • Ciao Alessandro. Su rapporti in tempo reale li vedi subito nella sezione eventi. Il resto lo vedi dopo 24 ore. A presto!

Recent Posts

Attribuzioni errate in GA4: cause e soluzioni al problema

Negli ultimi mesi hai notato in Google Analytics 4 un calo improvviso e inspiegabile nelle…

3 mesi ago

Come creare una Dashboard Ecommerce per analizzare i dati degli acquisti Nuovi e di Ritorno

Se ti trovi su questa guida è perché hai compreso che solo attraverso la Data…

4 mesi ago

Consent Mode v2 e calo dei dati delle audience e del traffico in Google Ads: cause e soluzioni

Da quando hai configurato la Consent Mode v2 (CM v2) hai notato cali improvvisi o…

6 mesi ago

Data Leak Google: Chrome e le implicazioni per la Privacy e la Digital Analytics

Premesso che non è possibile conoscere l'esatto funzionamento né di Chrome, né degli algoritmi di…

6 mesi ago

Come creare Report in GA4 per analizzare campagne advertising e marketing con UTM

Da quale canale di marketing arriva il maggior numero di conversioni? Quale campagna di marketing…

6 mesi ago