1var metricClickEvent = metricClickEvent || ""; 2var metricEventUrl = metricEventUrl || ""; 3var metricLoadEvent = metricLoadEvent || ""; 4 5const metricVisibilitySpy = (callback) => { 6 const observer = new IntersectionObserver( 7 (entries) => { 8 entries.forEach((entry) => { 9 if (entry.isIntersecting) { 10 callback(entry.target); 11 // ÐÑекÑаÑаем наблÑдение поÑле пеÑвого показа 12 observer.unobserve(entry.target); 13 } 14 }); 15 }, 16 { threshold: 0, rootMargin: "0px" } 17 ); 18 19 return { 20 observe: (element) => observer.observe(element), 21 disconnect: () => observer.disconnect(), 22 }; 23}; 24 25function sendBannerGA(event, data) { 26 const dataList = data.split(","); 27 const entity = dataList.shift(); 28 const id = dataList.shift(); 29 if (entity === "3") { 30 //send GA only for banners 31 if (window.ga && ga.create) { 32 ga("send", { 33 hitType: "event", 34 eventCategory: "banner-" + id, 35 eventAction: event === "1" ? "click" : "load", 36 }); 37 } else console.log("GA not loaded"); 38 } 39} 40 41const emitter = { 42 send(event, data) { 43 const xhttp = new XMLHttpRequest(); 44 xhttp.open("POST", metricEventUrl + "/?p=" + event + "," + data, true); 45 xhttp.send(); 46 //sendBannerGA(event, data); 47 }, 48 externalSend(url) { 49 const iframe = document.createElement("iframe"); 50 iframe.height = 0; 51 iframe.src = url; 52 document.body.appendChild(iframe); 53 }, 54}; 55 56const metric = { 57 spy: null, 58 clickedElements: new WeakSet(), 59 handleClick() { 60 document.addEventListener("click", (e) => { 61 const mark = e.target.closest(".pr-mark, .pr-mark-note"); 62 if (mark && !mark.closest("a[href]")) return; 63 const element = e.target.closest("[data-metric-click]"); 64 if (element && !this.clickedElements.has(element)) { 65 this.clickedElements.add(element); 66 emitter.send(metricClickEvent, element.dataset.metricClick); 67 if (element.dataset.metricExternalClick) emitter.externalSend(element.dataset.metricExternalClick); 68 } 69 }); 70 }, 71 handleLoad() { 72 this.spy = metricVisibilitySpy((element) => { 73 try { 74 emitter.send(metricLoadEvent, element.dataset.metricLoad); 75 if (element.dataset.metricExternalLoad) emitter.externalSend(element.dataset.metricExternalLoad); 76 } catch (e) { 77 console.log(e); 78 } 79 }); 80 81 document.querySelectorAll("[data-metric-load]").forEach((item) => this.spy.observe(item)); 82 }, 83 // ÐбÑабаÑÑваем динамиÑеÑки добавленнÑе ÑлеменÑÑ 84 watchDynamicElements() { 85 const observer = new MutationObserver((mutations) => { 86 mutations.forEach((mutation) => { 87 mutation.addedNodes.forEach((node) => { 88 if (node.nodeType === 1) { 89 // ÐÑовеÑÑем Ñам ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸ его поÑомков 90 if (node.dataset?.metricLoad) this.spy.observe(node); 91 node.querySelectorAll?.("[data-metric-load]").forEach((item) => this.spy.observe(item)); 92 } 93 }); 94 }); 95 }); 96 97 observer.observe(document.body, { childList: true, subtree: true }); 98 }, 99 init() { 100 this.handleClick(); 101 this.handleLoad(); 102 this.watchDynamicElements(); 103 }, 104}; 105 106metric.init();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.