How to get the percentage page scrolled using jquery onHandler?

vdevaraj
Visitor
vdevaraj

If I were to use the jQuery onHandler (1.7 and above) extension to add the following line of code to get the percent page scrolled and pass it to a variable in the data layer:

 

100 * $(window).scrollTop() / ($(document).height() - $(window).height());

 

what do I set the jQuery Selector to? We set it as window but that does not seem to work.

 

 

10 REPLIES 10

How to get the percentage page scrolled using jquery onHandler?

kathleen_jo
Employee Emeritus
kathleen_jo

Hello @vdevaraj. Excellent question. So I have 2 different ways to handle scroll tracking. One comes from our very own @jason_paddock. It's scoped to DOM ready and will fire a utag.link when the user passes 25%, 50%, 75%, and 100% scrolled. Here is the jQuery version:

 

try{
  //Global variable to keep track of which events we have already fired.
  window.scrollTracker = {
    "25" : 0,
    "50" : 0,
    "75" : 0,
    "100" : 0
  };
  jQuery(window).on('scroll', function(){
    //Capture the full length of the page
    var windowHeight = jQuery(document).height();
    //Capture where the top of the page is after scroll
    var currentPosition = jQuery(document).scrollTop();
    //Capture how many pixels can be viewed by the user
    var windowViewingArea = jQuery(window).height();
    //Figure out the bottom of what the user has scrolled to
    var bottomScrollPosition = currentPosition + windowViewingArea;
    //Figure out the rounded percentage of how much was scrolled
    var percentScrolled = parseInt((bottomScrollPosition / windowHeight * 100).toFixed(0));
    utag.DB('User scrolled '+percentScrolled+'%');
    //Store a variable to see if we can post the event
    var fireEvent = 0;
    //Store which quarter the user scrolled to
    var scrollBucket = 0;
    if(percentScrolled >= 25 && percentScrolled < 50){
      if(scrollTracker["25"] === 0){
        fireEvent = 1;
        scrollTracker["25"] = 1;
        scrollBucket = "25";
      }
    }else if(percentScrolled >= 50 && percentScrolled < 75){
      if(scrollTracker["50"] === 0){
        fireEvent = 1;
        scrollTracker["50"] = 1;
        scrollBucket = "50";
      }
    }else if(percentScrolled >= 75 && percentScrolled < 100){
      if(scrollTracker["75"] === 0){
        fireEvent = 1;
        scrollTracker["75"] = 1;
        scrollBucket = "75";
      }
    }else if(percentScrolled === 100){
      if(scrollTracker["100"] === 0){
        fireEvent = 1;
        scrollTracker["100"] = 1;
        scrollBucket = "100";
      }
    }
    if(fireEvent !== 0){
      utag.DB('sending event for '+scrollBucket+' bucket');
      utag.link({
        event_name: 'user_scroll',
        event_category: 'Behavior',
        event_action: 'Scroll',
        event_label: scrollBucket
      });
    }
  });
}catch(e){
  utag.DB('Error with performing the scroll tracker: '+e);
}

 And here is the JavaScript version:

 

if (!window.addEvent) {
    window.addEvent = function (element, evnt, funct) {
        try{
            if (element.attachEvent) {
                return element.attachEvent('on' + evnt, funct);
            }
            return element.addEventListener(evnt, funct, false);
        }catch(e){
            try{
                console.log('addEvent failed: '+e);
            }catch(e){}
        }
    };
}

try{
  utag.ut.scrollTracker = { 
    1: false, 
    2: false, 
    3: false, 
    4: false 
  };
  addEvent(window, 'scroll', function () {
    var html = document.documentElement;
    var body = document.body;
    var viewPort = {
      yScroll: window.pageYOffset || (html && html.scrollTop) || body.scrollTop,
      hScroll: document.compatMode === 'CSS1Compat' ? html.clientHeight || window.innerHeight || 0 : body.clientHeight || 0
    },
    windowHeight = Math.max(body.scrollHeight, html.scrollHeight, body.offsetHeight, html.offsetHeight, body.clientHeight, html.clientHeight),
    quartile = Number(((viewPort.hScroll + viewPort.yScroll) / windowHeight * 4)).toFixed(0);
    
    for(var key in utag.ut.scrollTracker){
      if (key <= quartile && !utag.ut.scrollTracker[key]) {
        utag.link({ 
          "event_name" : "user_scroll",
          "event_category" : "Behavior",
          "event_action" : "Scroll",        
          "event_label": key * 25,
        });
        utag.ut.scrollTracker[key] = true;
      }
    }
  });
}catch(e){
  utag.DB('Error with performing the scroll tracker: '+e);
}

There is also this solution from our amazing @stuart_roskelle:

 

http://blog.stuartrosk.com/index.php?controller=post&action=view&id_post=8

 

Now, in order to get an accurate percentage, you actually have to listen to the scroll event on the page and track the percentage, and only report it once per milestone (complete percent page viewed is typically done by setting a cookie with the scroll, then retrieving it on the next page). In the case of this plugin, it puts the percentage into buckets, then sends events when those buckets are reached.

 

I hope this helps @vdevaraj. Let us know if it does not. 

 

Remember to give me a kudo if you like my post! Accepting my post as a solution is even better! Also remember that search is your friend.

How to get the percentage page scrolled using jquery onHandler?

vdevaraj
Visitor
vdevaraj

@kathleen_jo Thank you so much!

How to get the percentage page scrolled using jquery onHandler?

kathleen_jo
Employee Emeritus
kathleen_jo

Thank you, however, the credit all goes to @stuart_roskelle and @jason_paddock. I am simply the messenger. 

 

Let us know which version worked best for you if you have time @vdevaraj. Have a great day!

Remember to give me a kudo if you like my post! Accepting my post as a solution is even better! Also remember that search is your friend.

How to get the percentage page scrolled using jquery onHandler?

vdevaraj
Visitor
vdevaraj

@kathleen_jo @jason_paddock

 

Hey Kathleen, (and Jason), thanks so much for sharing both the jQuery and the JS versions. The jQuery version seems to work well with our Tealium implementation. The Javascript version for unknown reasons breaks our Tealium utag. Here is what we did to integrate the jQuery script but for some reason we have not been successful yet in getting the data out to our s.prop65 (which is the SiteCatalyst variable that receives the percent page viewed value and populates our reporting suites in SiteCatalyst):

 

  1. Copied the jQuery code from @jason_paddock, pasted it into an extension called pp_scroll. The pp_scroll is a javascript extension scoped to all tags.
  2. In the data layer created 2 variables
    1. percent_page_scrolled as a UDO variable
    2. ppscroll as a first-party cookie
  3. Created a jQuery onHandler called percent_page_scrolled. Here is how we configured it:
    1. Scoped to DOM Ready
    2. Passed * to jQuery Selector
    3. Set Trigger on to mousedown
    4. Set tracking event to link
    5. Set percent_page_scroll to $window.on(‘scroll’, function ());
  4. We then created persist data value extension called Persist ppscroll. Here is how we configured that one:
    1. Scoped it to all tags
    2. Persist variable percent_page_scroll
    3. Duration: session
    4. Update: Allow update on page view
    5. Condition: percent_page_scrolled  is populated
    6. Store in cookie: ppscroll
  5. Finally in the Tags -> Appmeasurement for SiteCatalyst we have set ppscroll to pass the value to prop65

We pushed this to our QA environment.So far it has not broken our existing implementation but we do not see the prop65 receiving the percent scrolled value. Any ideas where we can improve or change what we have done?

 

Any light that you can shed on this would be very much appreciated!!

 

Thanks!

How to get the percentage page scrolled using jquery onHandler?

jason_paddock
Employee Emeritus
jason_paddock

Hi @vdevaraj,

Sorry you're having issues with the JS extension.  I'm thinking the issue has to do with the setup that you described.  

 

Either code block should be scoped to DOM Ready only.  It shouldn't be scoped to all tags as this will create multiple scroll listeners and you don't want that.  I would recommend updating the utag.link section of the code to change event_label to percent_page_scrolled.  I would think that you would want percent_page_scrolled mapped to prop65 in SiteCat.  You can add any additional data points that you want in this utag.link call so that it can send the data to your tags. 

 

You will want to remove the jQuery onhandler extension as well as this is going to give you undesired results.

 

Setting a cookie based on this value is fine, but I'm not sure I understand when you'll use the cookie value to send to SiteCat.  If you're wanting to set the cookie, how you described your setup is correct.

 

If you're still having issues, please reach out to your account manager and we'll be able to assist with setting up the proper configuration in your account.

 

Thanks!

How to get the percentage page scrolled using jquery onHandler?

vdevaraj
Visitor
vdevaraj

@jason_paddock@kathleen_jo - Thanks @john_oren

 

1) We used some of the logic in your code and mixed/matched with a piece of code I found on http://editor.javascriptkit.com/?eg=scrolltop-pct2

2) The reason we needed to persist the scrolled value was we wanted to wait until we got to the next page to pass the percent page scrolled to s.prop65. So prop64 (which is the previous page URL) and prop65 (which is the percent scrolled on the previous page) can be co-related. But I removed the persist data on percentage scrolled because it was causing issues

 

So here is the JS code we have now that is working. Unfortunately the code sets the ppscroll cookie for a day. We are still figuring out how to set the ppscroll cookie just for a page view. But the code works for now:

 

 

function getDocHeight() {
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
}

var winheight, docheight, trackLength, throttlescroll;

function getmeasurements(){
winheight= window.innerHeight || (document.documentElement || document.body).clientHeight;
docheight = getDocHeight();
trackLength = docheight - winheight;
}

function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length,c.length);
}
}
return "";
}

function setCookie(c_name, value, exdays) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()) + "; path=/";

document.cookie = c_name + "=" + c_value;
}

function amountscrolled(){
if (ppscrollcookie == null || ppscrollcookie == "")
{
var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;
var percentScrolled = Math.floor(scrollTop/trackLength * 100) // gets percentage scrolled (ie: 80 or NaN if tracklength == 0);
var percent_page_scrolled = "0";
if(percentScrolled > 0 && percentScrolled <= 25)
{
percent_page_scrolled = "25";
setCookie("ppscroll", percent_page_scrolled, 1);
}
else if (percentScrolled > 25 && percentScrolled <= 50)
{
percent_page_scrolled = "50";
setCookie("ppscroll", percent_page_scrolled, 1);
}
else if(percentScrolled > 50 && percentScrolled <= 75)
{
percent_page_scrolled = "75";
setCookie("ppscroll", percent_page_scrolled, 1);
}
else if(percentScrolled > 75 && percentScrolled <= 100)
{
percent_page_scrolled = "100";
setCookie("ppscroll", percent_page_scrolled, 1);
}
console.log(percent_page_scrolled);
}
else
{
setCookie("ppscroll", ppscrollcookie, 1);
}
}

getmeasurements();
var ppscrollcookie = getCookie('ppscroll');
console.log("Scroll Percent Present--> "+ppscrollcookie);

window.addEventListener("resize", function(){
getmeasurements();
}, false);

window.addEventListener("scroll", function(){
clearTimeout(throttlescroll)
throttlescroll = setTimeout(function(){ // throttle code inside scroll to once every 50 milliseconds
amountscrolled();
}, 50)
}, false);

How to get the percentage page scrolled using jquery onHandler?

Seamusmcf
Visitor
Seamusmcf

Hi @jason_paddock 

 

I am trying to deploy a modal offer using Tealium's modal offer extension once the user scrolls to 75% of the website. Could you provide me with a method of doing so? would I need to set a cookie for when they reach 75% and then deploy? any advice here would be much appericated.

 

Thanks! 

 

 

How to get the percentage page scrolled using jquery onHandler?

jason_paddock
Employee Emeritus
jason_paddock

Hi @Seamusmcf,

 

If you're using my default code, you would add a condition to the Modal Offer extension that fire when event_name equals user_scroll and event_label equals 75.

 

When this event comes in, that should bring up your offer.

 

If you want to do anything more advanced with the logic on when to trigger the extension, this is code that runs inside of utag.js:

 utag.ut.loader({
src: utag.cfg.path + 'utag.modalExt_56.js?utv=' + utag.cfg.v,
cb: function() {
utag.extn.mdlW.load();
}
});

 

You will want to replace utag.modalExt_56.js with the actual extension id for your modal offer extension.

 

Let us know how that works.

 

Thanks

Highlighted

How to get the percentage page scrolled using jquery onHandler?

SlingWing90
Visitor
SlingWing90

Hello everyone,

 

is it also possible to integrate responsive design into this js-code?

For instance four viewports ("large desktop", "desktop", "tablet", "mobile") and these viewports should be triggered in the event action

 

Kind Regards

How to get the percentage page scrolled using jquery onHandler?

pascalreder
Visitor
pascalreder

Hi,
We have implemented the JS solution and are sending the data to Adobe and to Google, using the utag.link function. 

utag.link({
'tealium_event': 'scrolling_to_the_bottom',
'some_evar': 'Scrolling to the bottom',
'some_prop' : 'Scrolling to the bottom',
'ga_eventCategory' : 'page depth',
'ga_eventAction' : 'scroll',
'ga_eventLabel' : 'bottom'
});

To Adobe we can see one request and the data is only being sent once. However, to GA, we have two requests and the data is being sent twice (see screenshot attached). 

When checking the numbers in GA, we see a huge discrepancy between unique events and events. 

Any idea how we can get rid of the double-sending of data to GA?

Best

Pascal

Bug.png