· 4 years ago · Sep 02, 2021, 11:08 AM
1<script type="text/javascript" id="gtm-vimeo-tracking">
2;(function (document, window, config) {
3
4 'use strict';
5 // The API won't work on LT IE9, so we bail if we detect those UAs
6 if (navigator.userAgent.match(/MSIE [678]\./gi)) return;
7
8 config = cleanConfig(config);
9
10 var handle = getHandler(config.syntax);
11
12 if (document.readyState !== 'loading') {
13
14 init();
15
16 } else {
17
18 document.addEventListener('DOMContentLoaded', init);
19
20 }
21
22 // Watch for new iframes popping in
23 document.addEventListener('load', init, true);
24
25 function init() {
26
27 var videos = filter_(selectAllTags_('iframe'), isVimeo);
28
29 if (!videos.length) return;
30
31 loadApi(function () {
32
33 forEach_(videos, listenTo);
34
35 });
36
37 }
38
39 function isVimeo(el) {
40
41 return el.src.indexOf('player.vimeo.com/video/') > -1;
42
43 }
44
45 function loadApi(callback) {
46
47 if (isUndefined_(window.Vimeo)) {
48
49 loadScript('https://player.vimeo.com/api/player.js', callback);
50
51 } else {
52
53 callback();
54
55 }
56
57 }
58
59 function listenTo(el) {
60
61 if (el.__vimeoTracked) return;
62
63 el.__vimeoTracked = true;
64
65 var video = new Vimeo.Player(el);
66 var percentages = config._track.percentages;
67 var eventNameDict = {
68 'Play': 'play',
69 'Pause': 'pause',
70 'Watch to End': 'ended'
71 };
72 var cache = {};
73
74
75 video.getVideoTitle().then(function (title) {
76 forEach_(['Play', 'Pause', 'Watch to End'], function (key) {
77
78 if (config.events[key]) {
79
80 video.on(eventNameDict[key], function () {
81 video.getEnded().then(function (ended) {
82 if (!ended) {
83 handle(key, title);
84 }
85 });
86 });
87
88
89
90 }
91
92 });
93
94 if (percentages) {
95
96 video.on('timeupdate', function (evt) {
97
98 var percentage = evt.percent;
99 var key;
100
101 for (key in percentages) {
102
103 if (percentage >= percentages[key] && !cache[key]) {
104
105 cache[key] = true;
106 handle(key, title);
107
108 }
109
110 }
111
112 });
113
114 }
115 });
116
117 }
118
119 function cleanConfig(config) {
120
121 config = extend_({}, {
122 events: {
123 'Play': true,
124 'Pause': true,
125 'Watch to End': true
126 },
127 percentages: {
128 each: [],
129 every: []
130 }
131 }, config);
132
133 forEach_(['each', 'every'], function (setting) {
134
135 var vals = config.percentages[setting];
136
137 if (!isArray_(vals)) vals = [vals];
138
139 if (vals) config.percentages[setting] = map_(vals, Number);
140
141 });
142
143 var points = [].concat(config.percentages.each);
144
145 if (config.percentages.every) {
146
147 forEach_(config.percentages.every, function (val) {
148
149 var n = 100 / val;
150 var every = [];
151 var i;
152
153 for (i = 1; i < n; i++) every.push(val * i);
154
155 points = points.concat(filter_(every, function (val) {
156
157 return val > 0.0 && val < 100.0;
158
159 }));
160
161 });
162
163 }
164
165 var percentages = reduce_(points, function (prev, curr) {
166
167 prev[curr + '%'] = curr / 100.0;
168 return prev;
169
170 }, {});
171
172 config._track = {
173 percentages: percentages
174 };
175
176 return config;
177
178 }
179
180 function getHandler(syntax) {
181
182 syntax = syntax || {};
183
184 var gtmGlobal = syntax.name || 'dataLayer';
185 var uaGlobal = syntax.name || window.GoogleAnalyticsObject || 'ga';
186 var clGlobal = '_gaq';
187 var dataLayer;
188
189 var handlers = {
190 'gtm': function (state, title) {
191
192 dataLayer.push({
193 event: 'video',
194 attributes: {
195 videoAction: state,
196 videoTitle: title
197 }
198 });
199
200 },
201 'cl': function (state) {
202
203 window[clGlobal].push(['_trackEvent', 'Videos', state]);
204
205 },
206 'ua': function (state) {
207
208 window[uaGlobal]('send', 'event', 'Videos', state);
209
210 }
211 };
212
213 switch (syntax.type) {
214
215 case 'gtm':
216
217 dataLayer = window[gtmGlobal] = window[gtmGlobal] || [];
218 break;
219
220 case 'ua':
221
222 window[uaGlobal] = window[uaGlobal] || function () {
223
224 (window[uaGlobal].q = window[uaGlobal].q || []).push(arguments);
225
226 };
227 window[uaGlobal].l = +new Date();
228 break;
229
230 case 'cl':
231
232 window[clGlobal] = window[clGlobal] || [];
233 break;
234
235 default:
236
237 if (!isUndefined_(window[gtmGlobal])) {
238
239 syntax.type = 'gtm';
240 dataLayer = window[gtmGlobal] = window[gtmGlobal] || [];
241
242 } else if (uaGlobal && !isUndefined_(window[uaGlobal])) {
243
244 syntax.type = 'ua';
245
246 } else if (!isUndefined_(window[clGlobal]) && !isUndefined_(window[clGlobal].push)) {
247
248 syntax.type = 'cl';
249
250 }
251 break;
252 }
253
254 return handlers[syntax.type];
255
256 }
257
258 function extend_() {
259
260 var args = [].slice.call(arguments);
261 var dst = args.shift();
262 var src;
263 var key;
264 var i;
265
266 for (i = 0; i < args.length; i++) {
267
268 src = args[i];
269
270 for (key in src) {
271
272 dst[key] = src[key];
273
274 }
275
276 }
277
278 return dst;
279
280 }
281
282 function isArray_(o) {
283
284 if (Array.isArray_) return Array.isArray_(o);
285
286 return Object.prototype.toString.call(o) === '[object Array]';
287
288 }
289
290 function forEach_(arr, fn) {
291
292 if (Array.prototype.forEach_) return arr.forEach.call(arr, fn);
293
294 var i;
295
296 for (i = 0; i < arr.length; i++) {
297
298 fn.call(window, arr[i], i, arr);
299
300 }
301
302 }
303
304 function map_(arr, fn) {
305
306 if (Array.prototype.map_) return arr.map.call(arr, fn);
307
308 var newArr = [];
309
310 forEach_(arr, function (el, ind, arr) {
311
312 newArr.push(fn.call(window, el, ind, arr));
313
314 });
315
316 return newArr;
317
318 }
319
320
321 function filter_(arr, fn) {
322
323 if (Array.prototype.filter) return arr.filter.call(arr, fn);
324
325 var newArr = [];
326
327 forEach_(arr, function (el, ind, arr) {
328
329 if (fn.call(window, el, ind, arr)) newArr.push(el);
330
331 });
332
333 return newArr;
334
335 }
336
337 function reduce_(arr, fn, init) {
338
339 if (Array.prototype.reduce) return arr.reduce.call(arr, fn, init);
340
341 var result = init;
342 var el;
343 var i;
344
345 for (i = 0; i < arr.length; i++) {
346
347 el = arr[i];
348 result = fn.call(window, result, el, arr, i);
349
350 }
351
352 return result;
353
354 }
355
356 function isUndefined_(thing) {
357
358 return typeof thing === 'undefined';
359
360 }
361
362 function selectAllTags_(tags) {
363
364 if (!isArray_(tags)) tags = [tags];
365
366 return [].slice.call(document.querySelectorAll(tags.join()));
367
368 }
369
370 function loadScript(src, callback) {
371
372 var f, s;
373
374 f = document.getElementsByTagName('script')[0];
375 s = document.createElement('script');
376 s.onload = callCallback;
377 s.src = src;
378 s.async = true;
379
380 f.parentNode.insertBefore(s, f);
381
382 function callCallback() {
383
384 if (callback) {
385
386 callback();
387 s.onload = null;
388
389 }
390
391 }
392
393 }
394
395})(document, window, {
396 'events': {
397 'Play': true,
398 'Pause': true,
399 'Watch to End': false
400 },
401 'percentages': {
402 'every': 25,
403 'each': [100]
404 }
405});
406</script>