GTM 常用的 10 個 JavaScript Tricks

記錄了 Google Tag Manager 在 Custom HTML Tags 或 Custom JavaScript Variables 中經常使用的技巧。

檢查瀏覽器的兼容性
不支援的替代方法

1. String methods

.trim() 去掉字串前後的空白
“ Oh no! Leading AND trailing whitespace!! “.trim();
// "Oh no! Leading AND trailing whitespace!!"

.replace() 替換內容的字元 或 使用正則表達式替換字元
“Food”.replace(‘o’, ‘e’); // “Feod”
“Food”.replace(/o/g, ‘e’); // “Feed”
.toUpperCase() and .toLowerCase() 改變字元大小寫
“MixED CaSe String”.toLowerCase(); //小寫

.substring() 只回傳字串、返回字串的一部份
“?some-query-key=some-query-value”.substring(1);
// Returns: “some-query-key=some-query-value”
“id: 12345–12345”.substring(4,9);
// Returns: “12345”
.split() 分割字串
“get the second word of this sentence”.split(‘ ‘)[1];
// “the”
總和應用
var str = "capitalize the first letter of this string, please!";
str = str.replace(/^./, str.substring(0,1).toUpperCase());

2. Array methods

filter()
遍歷Array每個項目,並返回一個通過檢查回調的 new Array
someArray.filter(function(eachItem) { 
return eachItem === someCondition;
});
eachItem是一個變數,用來處理數組時存儲每個Array的項目。
若回調返回true,則該項被添加到返回的new Array中,若返回false,則被丟棄。
example:
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'event' : 'addMe!'
},{
'event' : 'doNotAddMe!'
});
var newArray = window.dataLayer.filter(function(item) {
return item.event === 'addMe!';
});
// Returns: [{'event' : 'addMe!'}]
檢查屬性event的每個項目,如果該屬性的值為addMe!,則返回true。
因此返回的數組只有 key-value pair 'event' : 'addMe!' 的元素。

forEach()
接收array的每個項目,並能對項目作任何事,比 for-loop 更直觀可讀
var array = ["I", 4, 2, true, "love", [1,2,3], {chocolate: 'too'}, "you"];
var newArray = [];
example:
array.forEach(function(item) {
if (typeof item === 'string') {
newArray.push(item);
}
});
newArray.join(" ");
// Result: "I love you"

map()
再次遍歷array的每個項目,但是這次回調中的代碼針對array的每個項目執行,並返回一個帶有結果的 new array。
array.map(function(item) {
return doSomething(item);
});
example:
var array = [1,2,3,4,5];
array.map(function(item) {
return item * 2;
});
// Result: [2,4,6,8,10]
example:
var array = [" please ", " trim", " us "];
array.map(function(item) {
return item.trim();
});
// Result: ["please", "trim", "us"];

reduce()
您提供一個累加器的功能,然後array的每個項目對這個累加器進行操作。也可以向累加器提供初始值。
array.reduce(function(accumulator, item) {
accumulator.doSomethingWith(item);
return accumulator;
}, initialValue);
example: calculate the sum of all even numbers in the array
var array = [1,6,3,4,12,17,21,27,30];
array.reduce(function(accumulator, item) {
if (item % 2 === 0) {
accumulator += item;
}
return accumulator;
}, 0);
// Returns: 52
example: concatenate a string of all product IDs in array
var array = [{
"id" : "firstId",
"name" : "T-shirts"
},{
"id" : "secondId",
"name" : "Pants"
},{
"id" : "thirdId",
"name" : "shoes"
}];
array.reduce(function(accumulator, item) {
accumulator.push(item.id);
return accumulator;
}, []).join();
// Returns: "firstId,secondId,thirdId"

3. Ternary operator

條件檢查的簡寫 1:
// BEFORE:
if (something) {
somethingElse();
} else {
somethingDifferent();
}
// AFTER:
something ? somethingElse() : somethingDifferent();
條件檢查的簡寫 2:
// BEFORE:
if (document.querySelector('#findThisId') !== null) {
return document.querySelector('#findThisId');
} else {
return "Not found!";
}
// AFTER:
return document.querySelector('#findThisId') ? document.querySelector('#findThisId') : "Not found!";
// EVEN BETTER:
return document.querySelector('#findThisId') || "Not found!";

4. return {{Click URL}}.indexOf({{Page Hostname}}) > -1

點擊的元素URL包含當頁的hostname,則返回true,否則返回false。
換句話說,若點擊的鏈接是內部的,則返回true,若為外部連結,則返回false。
example:
function() {
return {{Click URL}}.indexOf({{Page Hostname}}) > -1;
}

5. return {{Click URL}}.split(‘/’).pop()

追蹤文件下載時返回實際下載的文件名。return 點擊URL '/' 之後的字串。
example:
function() {
// Example: https://www.simoahava.com/downloads/download_me.pdf
return {{Click URL}}.split('/').pop();
// Returns: download_me.pdf
}

6. Create a random, unique GUID

在GTM創建一個隨機的ID
例如若要測量session IDs,或要為每個頁面分配唯一的識別ID,則可以此變量來實現。
該變量創建一個 GUID string (“Globally Unique Identifier”)
即使不保證唯一性,因為他仍是有微小的機會重複。
example:
function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}

7. Return an ISO-formatted timestamp

將當前客戶端時間轉換為適當的可讀時間標記,包含時區,可知道users和自己的時差,所以發送到 Google Analytics 時就可有他的時間軸。
example:
function() {
var now = new Date();
var tzo = -now.getTimezoneOffset();
var dif = tzo >= 0 ? '+' : '-';
var pad = function(num) {
var norm = Math.abs(Math.floor(num));
return (norm < 10 ? '0' : '') + norm;
};
return now.getFullYear()
+ '-' + pad(now.getMonth()+1)
+ '-' + pad(now.getDate())
+ 'T' + pad(now.getHours())
+ ':' + pad(now.getMinutes())
+ ':' + pad(now.getSeconds())
+ '.' + pad(now.getMilliseconds())
+ dif + pad(tzo / 60)
+ ':' + pad(tzo % 60);
// Returns, for example: 2017-01-18T11:58:32.977+02:00
}

8. matches() polyfill

使用DOM時,能夠識別元素很重要,除了可使用 CSS selectors,只需要可以使用它來檢查任何給定的元素是否匹配這些選擇器。
可使用 Element.matches(someSelector)方法,但不被 stellar browser support, even with prefixes. 支援,所以使用 polyfill 解決方案,即可隨時使用 .matches(),無需擔心瀏覽器支援程度。
// Check if the parent of the clicked element has ID #testMe
var el = {{Click Element}};
console.log(el.parentElement.matches('#testMe'));
// RESULT: true or false
要使用 polyfill,必須儘早在頁面加載順序中將其添加到 JavaScript,或者使用Google Tag Manager。
在 Google Tag Manager,需要在容器加載順序(即具有高標記優先級的所有頁面觸發器)中儘早觸發 Custom HTML Tag。
example:
<script>
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
</script>
polyfill修改了 Element 的 actual prototype,這些元素都是HTML和DOM元素所繼承的。 修改 prototype 後,您可以對所有的 GTM 和 site JavaScript 放心使用matches()。

9. DOM traversal

有時需要往上或往下爬 Document Object Model,若Trigger設定為 Click / All Elements trigger,雖可定位已點擊的實際元素,但不一定是想追蹤的 ,例如下方結構:
<a href="takemeaway.html">
<button id="clickMe">
<span>Click Me!</span>
</button>
</a>
若 Trigger 設定為點擊所有元素,則會獲得 <span> 裡的 Click Me!,若想追蹤 <a href="takemeaway.html">元素,可使用自訂JavaScript變數返回最接近點擊元素的 DOM tree。
function() {
var el = {{Click Element}};
while (!el.matches('a') && !el.matches('body')) {
el = el.parentElement;
}
return el.matches('a') ? el : undefined;
}
NOTE!因取決於matches()方法,所以不要忘了先 polyfill!
此自訂JavaScript變數爬上DOM直到達到它找到的第一個鏈接元素('a'),之後它返回此元素。 如果沒有找到('a'),則返回 undefined。

10. Set browser cookies with ease

Cookie是在瀏覽器中存儲信息的很常使用的方法。 
way of storing information in the browser.
設定一個 {{Set Cookie}} Custom JavaScript Variable:
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;
}
}
調用cookie方式 :
{{Set Cookie}}('test', 'true', 10000, '/', 'simoahava.com');
{{Set Cookie}} 此自訂變數需回傳五個變數:
name(必要): the name of the cookie (string)
value(必要): the value of the cookie (string)
ms(秒): expiration time of the cookie in milliseconds. If unset, defaults to a Session cookie (expires when the browser is closed).
path: the path of the cookie. If unset, defaults to the current page path.
domain: the domain of the cookie. If unset, defaults to the current domain.
可以使用GTM中的 1st Party Cookie 來設置Cookie的檢索值。

文章來源

Like what you read? Give Tsai JC a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.