|
5 | 5 | // Internals |
6 | 6 | let map = new Map(); |
7 | 7 | let fragment = new DocumentFragment(); |
8 | | -let observer = new IntersectionObserver(handleIntersection, { rootMargin: "500px" }) |
| 8 | +let loadObserver = new IntersectionObserver(handleLoad, { rootMargin: "500px" }); |
| 9 | +let trackingObserver = new IntersectionObserver(handleTracking, { threshold: 0.25 }); |
9 | 10 |
|
10 | 11 | // Locker |
11 | 12 | export let locker; |
@@ -55,6 +56,18 @@ export class Zone { |
55 | 56 | map.set(val, this); |
56 | 57 | } |
57 | 58 |
|
| 59 | + /* |
| 60 | + * Getter/Setter for tracking |
| 61 | + */ |
| 62 | + |
| 63 | + get tracking() { |
| 64 | + return this.element.dataset.tracking; |
| 65 | + } |
| 66 | + |
| 67 | + set tracking(val) { |
| 68 | + this.element.dataset.tracking = val; |
| 69 | + } |
| 70 | + |
58 | 71 | /* |
59 | 72 | * Getters for element attributes |
60 | 73 | */ |
@@ -153,7 +166,12 @@ export class Zone { |
153 | 166 | this.log(this.msg || "zone moved into new location"); |
154 | 167 |
|
155 | 168 | // Observer for performance team |
156 | | - observer.observe(this.element); |
| 169 | + loadObserver.observe(this.element); |
| 170 | + |
| 171 | + // Tracking observer |
| 172 | + if(this.tracking) { |
| 173 | + trackingObserver.observe(this.element); |
| 174 | + } |
157 | 175 | } |
158 | 176 | } |
159 | 177 |
|
@@ -394,24 +412,53 @@ export function render() { |
394 | 412 | } |
395 | 413 |
|
396 | 414 | /* |
397 | | - * IntersectionObserver callback |
| 415 | + * Intersection callback |
398 | 416 | */ |
399 | 417 |
|
400 | | -function handleIntersection(entries, observer) { |
| 418 | +function handleLoad(entries, observer) { |
401 | 419 | entries.forEach((entry) => { |
402 | 420 | if(entry.isIntersecting) { |
403 | | - // Build the event |
404 | | - const loadZone = new CustomEvent("zone", { |
| 421 | + // Build the load event |
| 422 | + const intersectionEvent = new CustomEvent("zone", { |
405 | 423 | detail: { |
406 | 424 | id: entry.target.id |
407 | 425 | } |
408 | 426 | }); |
409 | 427 |
|
410 | 428 | // Send it |
411 | | - window.dispatchEvent(loadZone); |
| 429 | + window.dispatchEvent(intersectionEvent); |
| 430 | + |
| 431 | + // Only do this once |
| 432 | + loadObserver.unobserve(entry.target); |
| 433 | + } |
| 434 | + }); |
| 435 | +} |
| 436 | + |
| 437 | +/* |
| 438 | + * Tracking callback |
| 439 | + */ |
| 440 | + |
| 441 | +function handleTracking(entries, observer) { |
| 442 | + entries.forEach((entry) => { |
| 443 | + if(entry.isIntersecting) { |
| 444 | + // Build the tracking event if configured (Joe Grubbs spec) |
| 445 | + const trackEvent = new CustomEvent('trackcustomzones', { |
| 446 | + detail: { |
| 447 | + data: [ |
| 448 | + { |
| 449 | + zone: entry.target.id.replace(/zone-(el-)?/, ''), |
| 450 | + action: "impression", |
| 451 | + count: 1 |
| 452 | + } |
| 453 | + ] |
| 454 | + } |
| 455 | + }); |
| 456 | + |
| 457 | + // Send it |
| 458 | + window.dispatchEvent(trackEvent); |
412 | 459 |
|
413 | | - // Only do it once |
414 | | - observer.unobserve(entry.target); |
| 460 | + // Only do this once |
| 461 | + trackingObserver.unobserve(entry.target); |
415 | 462 | } |
416 | 463 | }); |
417 | 464 | } |
0 commit comments