GiacomoGalanti

persistent dataLayer

Mar 26th, 2020
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.14 KB | None | 0 0
  1. <script>
  2. (function() {
  3. // Set the timeout for when the dataLayer history should be purged. The default is 30 minutes.
  4. // The timeout needs to be in milliseconds.
  5. var timeout = 30*60*1000;
  6.  
  7. // Change dataLayerName only if you've defined another named for the dataLayer array in your
  8. // GTM container snippet.
  9. var dataLayerName = 'dataLayer';
  10.  
  11. // Don't change anything below.
  12. // Initial settings
  13. var initialLoad = true,
  14. oldPush = window[dataLayerName].push;
  15.  
  16. // Method to copy items from dataLayer from before the GTM container snippet was loaded.
  17. var backfillHistory = function() {
  18. var tempHistory = [],
  19. i = 0,
  20. len = window[dataLayerName].length - 1;
  21. for (; i < len; i++) {
  22. tempHistory.push(window[dataLayerName][i]);
  23. }
  24. return tempHistory;
  25. };
  26.  
  27. // Method to check if object is a plain object.
  28. // From https://bit.ly/2A3Fuqe
  29. var isPlainObject = function(value) {
  30. if (!value || typeof value !== 'object' || // Nulls, dates, etc.
  31. value.nodeType || // DOM nodes.
  32. value === value.window) { // Window objects.
  33. return false;
  34. }
  35. try {
  36. if (value.constructor && !value.hasOwnProperty('constructor') &&
  37. !value.constructor.prototype.hasOwnProperty('isPrototypeOf')) {
  38. return false;
  39. }
  40. } catch (e) {
  41. return false;
  42. }
  43. var key;
  44. for (key in value) {}
  45. return key === undefined || value.hasOwnProperty(key);
  46. };
  47.  
  48. // Method to merge the stored data model and the history model together.
  49. // From https://bit.ly/2FrPQWL
  50. var mergeStates = function(storedModel, historyModel) {
  51. for (var property in storedModel) {
  52. if (storedModel.hasOwnProperty(property)) {
  53. var storedProperty = storedModel[property];
  54. if (Array.isArray(storedProperty)) {
  55. if (!Array.isArray(historyModel[property])) historyModel[property] = [];
  56. mergeStates(storedProperty, historyModel[property]);
  57. } else if (isPlainObject(storedProperty)) {
  58. if (!isPlainObject(historyModel[property])) historyModel[property] = {};
  59. mergeStates(storedProperty, historyModel[property]);
  60. } else {
  61. historyModel[property] = storedProperty;
  62. }
  63. }
  64. }
  65. };
  66.  
  67. window[dataLayerName].push = function() {
  68. try {
  69.  
  70. // Build the history array from local storage
  71. window._dataLayerHistory = JSON.parse(
  72. window.localStorage.getItem('_dataLayerHistory') ||
  73. '{"timeout": null, "history": [], "model": {}}'
  74. );
  75.  
  76. // Initial settings
  77. var timeNow = new Date().getTime(),
  78. states = [].slice.call(arguments, 0),
  79. results = oldPush.apply(window[dataLayerName], states),
  80. oDataLayer = window[dataLayerName],
  81. dHistory = window._dataLayerHistory,
  82. oDataModel = window.google_tag_manager[{{Container ID}}].dataLayer.get({split: function() { return []; }});
  83.  
  84. // Method to reset the history array to the current page state only
  85. dHistory.reset = function() {
  86. dHistory.timeout = null;
  87. dHistory.history = backfillHistory();
  88. dHistory.model = {};
  89. mergeStates(oDataModel, dHistory.model);
  90. window.localStorage.setItem('_dataLayerHistory', JSON.stringify(dHistory));
  91. };
  92.  
  93. // From https://bit.ly/2A2ZcCG
  94. dHistory.model.get = function(key) {
  95. var target = dHistory.model;
  96. var split = key.split('.');
  97. for (var i = 0; i < split.length; i++) {
  98. if (target[split[i]] === undefined) return undefined;
  99. target = target[split[i]];
  100. }
  101. return target;
  102. };
  103.  
  104. // Add history if this is the initialization event itself
  105. if (initialLoad) {
  106. dHistory.history = dHistory.history.concat(backfillHistory());
  107. initialLoad = false;
  108. }
  109.  
  110. // If timeout is reached, reset the history array
  111. if (dHistory.hasOwnProperty('timeout') && dHistory.timeout < timeNow) {
  112. dHistory.reset();
  113. }
  114.  
  115. // Push latest item from dataLayer into the history array
  116. dHistory.history.push(oDataLayer[oDataLayer.length-1]);
  117.  
  118. // Merge GTM's data model with the history model
  119. mergeStates(oDataModel, dHistory.model);
  120.  
  121. // Update the timeout
  122. dHistory.timeout = timeNow + timeout;
  123.  
  124. // Write the new history into localStorage
  125. window.localStorage.setItem('_dataLayerHistory', JSON.stringify(dHistory));
  126. return results;
  127. } catch(e) {
  128. console.log('Problem interacting with dataLayer history: ' + e);
  129. var states = [].slice.call(arguments, 0),
  130. results = oldPush.apply(window[dataLayerName], states);
  131. return results;
  132. }
  133. };
  134. })();
  135. </script>
Add Comment
Please, Sign In to add comment