Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts

3,628 views

Published on

Here's my list of 10 JavaScript (related) concepts that I think all web analysts should understand at least on a basic level. A solid grasp of JavaScript is a base requirement for anyone working with the web browser.

Published in: Internet

MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts

  1. 1. Reaktor Mannerheimintie 2 00100, Helsinki Finland tel: +358 9 4152 0200 www.reaktor.com info@reaktor.com Confidential ©2015 Reaktor All rights reserved 10 javascript conceptsFor advanced (web) analytics implementation Simo Ahava Senior Data Advocate
  2. 2. Simo Ahava Senior Data Advocate, Reaktor Google Developer Expert, Google Analytics Blogger, developer, www.simoahava.com Twitter-er, @SimoAhava Google+:er, +SimoAhava
  3. 3. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 Get the basics right
  4. 4. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 Get the basics right Great JavaScript learning resources
  5. 5. http://www.codecademy.com/
  6. 6. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 1. Functions
  7. 7. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 1. Functions …multi-purpose, multi-use…
  8. 8. function (number1, number2) { someGlobalProperty.set(number1 * number2); return number1 * number2; } AVOID SIDE EFFECTS!
  9. 9. function () { var timeNow = new Date(); return function() { return "Time at initialization was ": timeNow; } } understand scope, utilize closures
  10. 10. function() { var jsonLd = document.querySelector('script[type*="ld+json"]'); return jsonLd ? JSON.parse(jsonLd.innerHTML) : {}; } function() { return {{JSON-LD}}.author.name || undefined; } Leverage return values for max flexibility!
  11. 11. function() { return function() { window.dataLayer.push({
 'event' : 'commandComplete' });
 }; } Modify state in closures, e.g. using hitCallback
  12. 12. http://www.w3schools.com/js/js_function_closures.asp https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures http://www.simoahava.com/analytics/variable-guide-google-tag-manager/#6 further reading
  13. 13. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 2. Data types
  14. 14. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 2. Data types …stay loose…
  15. 15. Number: 5 String: "five" Boolean: true Array: [1, 2, 3] Object: {name: "Simo"} Misc: undefined, null…
  16. 16. var five = "5"; five = 5; dynamic type
  17. 17. var five = "5"; var ten = five * 2;
 // ten === 10 loose type
  18. 18. typeof [1,2,3]; // "object" Array.isArray([1,2,3]); // true typeof undefined; // "undefined" typeof null; // "object"
 undefined === null; // false undefined == null; // true typeof NaN; // "number" isNaN(NaN); // true isNaN(null); // false NaN === NaN; // false weird stuff…
  19. 19. window.dataLayer.push({
 'event' : 'GAEvent', 'eventData' : {
 'cat' : 'Category Value', 'act' : 'Action Value', 'lab' : undefined, // PURGE 'val' : undefined // PURGE }
 }); use undefined to reset data layer variables
  20. 20. http://www.w3schools.com/js/js_datatypes.asp https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures http://www.simoahava.com/gtm-tips/undefined-dimensions-wont-get-sent/ further reading
  21. 21. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 3. HTTP requests
  22. 22. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 3. HTTP requests …loading resources without blocking the browser…
  23. 23. the container snippet is a script loader
  24. 24. it injects a script element into the dom
  25. 25. which, in turn, downloads the gtm library
  26. 26. <a href=url> <applet codebase=url> <area href=url> <base href=url> <blockquote cite=url> <body background=url> <del cite=url> <form action=url> <frame longdesc=url>, <frame src=url> <head profile=url> <iframe longdesc=url>, <iframe src=url> <img longdesc=url>, <img src=url>, <img usemap=url> all these html elements invoke an http request <input src=url>, <input usemap=url> <ins cite=url> <link href=url> <object classid=url>, <object codebase=url>, <object data=url>, <object usemap=url> <q cite=url> <script src=url> <audio src=url> <button formaction=url> <command icon=url> <embed src=url> <html manifest=url> <input formaction=url> <source src=url> <video poster=url>, <video src=url>
  27. 27. GA does both get and post depending on payload size
  28. 28. http://www.w3schools.com/ajax/ajax_xmlhttprequest_create.asp http://www.w3schools.com/tags/ref_httpmethods.asp https://developers.google.com/analytics/devguides/collection/protocol/v1/reference#transport further reading
  29. 29. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 4. Race conditions
  30. 30. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 4. Race conditions …last one over the finish line is a failed request…
  31. 31. async in the script tag means the resource is downloaded asynchronously
  32. 32. Synchronous: The web browser reads, requests, and executes from top-to-bottom, left-to-right. Asynchronous: The web browser reads and requests from top-to-bottom, left-to-right. 
 Execution depends on when the requests complete respectively.
  33. 33. Synchronous: The web browser reads, requests, and executes from top-to-bottom, left-to-right. Asynchronous: The web browser reads and requests from top-to-bottom, left-to-right. 
 Execution depends on when the requests complete respectively. Race condition: When the browser expects a proper sequence for executing commands, but this sequence cannot be guaranteed.
  34. 34. var jQLoad = document.createElement('script');
 jQLoad.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js';
 jQLoad.addEventListener('load', function() {
 window.dataLayer.push({
 'event' : 'jQueryComplete' }); }); document.head.appendChild(jQLoad); use callbacks to establish sequence
  35. 35. <script> (function() { var el = document.createElement('script'); el.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'; el.addEventListener('load', function() { google_tag_manager[{{Container ID}}].onHtmlSuccess({{HTML ID}}); }); document.head.appendChild(el); })(); </script> tag sequencing can be used but it’s tricky
  36. 36. http://callbackhell.com/ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise http://www.simoahava.com/analytics/understanding-tag-sequencing-in-google-tag-manager/ further reading
  37. 37. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 5. History manipulation
  38. 38. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 5. History manipulation …avoiding the dreaded page refresh…
  39. 39. window.history.pushState(
 { pageType: 'formThankYou' }, 'Form Success', '/thank-you/' ); pushstate creates a new history entry in the web browser
  40. 40. window.location = '#thank-you'; changing location to #hash does the same thing
  41. 41. window.history.replaceState(
 { pageType: 'formThankYou' }, 'Form Success', '/thank-you/' ); replacestate replaces the current history state
  42. 42. you can create triggers in gtm that react to these changes
  43. 43. https://developer.mozilla.org/en-US/docs/Web/API/History_API http://www.w3schools.com/js/js_window_history.asp http://www.simoahava.com/analytics/google-tag-manager-history-listener/ further reading
  44. 44. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 6. Browser storage
  45. 45. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 6. Browser storage …introducing state to a stateless environment…
  46. 46. function() { return function(name, value, ms, path, domain) { if (!name || !value) { return; } var d; var cpath = path ? '; path=' + path : ''; var cdomain = domain ? '; domain=' + domain : ''; var expires = ''; if (ms) { d = new Date(); d.setTime(d.getTime() + ms); expires = '; expires=' + d.toUTCString(); } document.cookie = name + "=" + value + expires + cpath + cdomain; } } browser cookies are useful for simple storage
  47. 47. {{Simo Cookie Solution}}('subscribe', 'true', 1800000, '/', 'simoahava.com'); browser cookies are useful for simple storage
  48. 48. if (window['Storage']) { localStorage.setItem('subscribe', 'true'); sessionStorage.setItem('subscribe', 'true'); } else { {{JS - setCookie}}('subscribe', 'true'); } // TO FETCH localStorage.getItem('subscribe'); sessionStorage.getItem('subscribe'); HTML5 STORAGE IS MORE flexible BUT CAN BE DIFFICULT TO MANAGE
  49. 49. http://www.w3schools.com/js/js_cookies.asp https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API http://www.simoahava.com/analytics/two-ways-to-persist-data-via-google-tag-manager/ further reading
  50. 50. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 7. DOM traversal
  51. 51. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 7. DOM traversal …needles in haystacks…
  52. 52. sometimes you need to retrieve an element without direct access to it
  53. 53. function() {
 return {{Click Element}}
 .parentElement
 .parentElement
 .parentElement
 .parentElement
 .parentElement;
 } clumsy
  54. 54. function() {
 var el = {{Click Element}};
 
 while (el.className !== 'content-sidebar-wrap' && el.tagName !== 'BODY') {
 el = el.parentElement; }
 
 return el.tagName !== 'BODY' ? el : undefined;
 } better
  55. 55. http://www.w3schools.com/js/js_htmldom_navigation.asp http://domenlightenment.com/ http://www.simoahava.com/analytics/node-relationships-gtm/ further reading
  56. 56. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 8. CSS selectors
  57. 57. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 8. CSS selectors …magnet for the needles…
  58. 58. the most useful operator in gtm triggers
  59. 59. css selectors let you identify elements on the page based on their unique position in the dom
  60. 60. http://www.w3schools.com/cssref/css_selectors.asp http://www.simoahava.com/analytics/matches-css-selector-operator-in-gtm-triggers/ further reading
  61. 61. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 9. jQuery
  62. 62. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 9. jQuery …machine which sorts the magnets…
  63. 63. function() {
 var el = {{Click Element}};
 
 while (el.className !== 'content-sidebar-wrap' && el.tagName !== 'BODY') {
 el = el.parentElement;
 
 return el.tagName !== 'BODY' ? el : undefined;
 } jQuery is excellent for abstracting many difficult issues with working js in the browser
  64. 64. function() {
 return jQuery({{Click Element}}).closest('.content-sidebar-wrap'); } jQuery is excellent for abstracting many difficult issues with working js in the browser
  65. 65. jQuery.post(
 'http://www.simoahava.com/', // URL {subscriber: 'true'}, // Payload function() { 
 window.dataLayer.push({'event' : 'requestComplete'});
 } // Callback
 ); jQuery is excellent for abstracting many difficult issues with working js in the browser
  66. 66. you can load it in a custom html tag, but remember the race condition
  67. 67. https://api.jquery.com/category/traversing/ http://api.jquery.com/ further reading
  68. 68. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 10. dataLayer
  69. 69. @SimoAhava from @ReaktorNow | #MeasureCamp | 10 Sep 2016 10. dataLayer …repository of semantic information - NOT just for GTM…
  70. 70. datalayer is a global javascript array with a modified .push()
  71. 71. Since it’s global, it’s easy to destroy
  72. 72. it’s a message bus, and gtm processes the messages as they come, and in sequence
  73. 73. note that .push() is the only proprietary method. others have no impact on gtm. window.dataLayer.pop(); // does nothing in GTM window.dataLayer.shift(); // does nothing in GTM window.dataLayer.splice(); // does nothing in GTM window.dataLayer.slice(); // does nothing in GTM window.dataLayer.push(); // does lots of things in GTM
  74. 74. https://github.com/google/data-layer-helper http://www.simoahava.com/analytics/data-layer/ further reading
  75. 75. simo.ahava@reaktor.com www.simoahava.com Twitter: @SimoAhava Google+: +SimoAhava

×