PageSourceSearch

https://forobeta.com/js/ForoBeta/Ads/beacon.js?v=2

js forobeta.com collected 2026-10-02 02:34:56 UTC 3,720 bytes, 106 lines download raw bytes

1/**
2 * ForoBeta/Ads — beacon de impresiones VIEWABLE (+ rotación A/B client-side).
3 *
4 * Cuenta una impresión cuando un banner ha estado al menos 50% visible durante 1s continuo
5 * (estándar MRC). Junta lo visto y manda UN solo navigator.sendBeacon a /anunciate-beacon.php.
6 *
7 * A/B (v2): un banner con prueba A/B se renderiza con AMBAS creatividades dentro de
8 * .fbAds-banner.fbAds-ab (cada variante = .fbAds-ab-v con data-fbads-variant 0|1, la B oculta).
9 * Como ~80% de las páginas anónimas salen de LSCache, la elección NO puede hacerse en el
10 * servidor (se congelaría): aquí se elige 50/50 por impresión, se muestra una y se reporta cuál
11 * (token "id" para variante 0, "id:1" para la B). Sin JS → queda visible la A (degradación amable).
12 *
13 * Solo los navegadores reales ejecutan JS → filtra de paso a los bots que no corren JS.
14 */
15(function () {
16	if (!('IntersectionObserver' in window) || !navigator.sendBeacon) { return; }
17
18	var seen = {};      // tokens ya contados en esta página
19	var pending = {};   // tokens vistos pendientes de enviar
20	var timer = null;
21
22	function flush() {
23		if (timer) { clearTimeout(timer); timer = null; }
24		var keys = Object.keys(pending);
25		if (!keys.length) { return; }
26		pending = {};
27		try {
28			navigator.sendBeacon('/anunciate-beacon.php', 'ids=' + keys.join(','));
29		} catch (e) {}
30	}
31
32	function schedule() {
33		if (timer) { return; }
34		timer = setTimeout(flush, 1500); // agrupa varios banners en un envío
35	}
36
37	// Token de conteo: "id" para variante 0 (compacto + compatible), "id:1" para la B.
38	function tokenFor(el) {
39		var id = el.getAttribute('data-fbads-id');
40		if (!id) { return null; }
41		var v = el.getAttribute('data-fbads-variant');
42		return (v && v !== '0') ? (id + ':' + v) : id;
43	}
44
45	var io = new IntersectionObserver(function (entries) {
46		entries.forEach(function (en) {
47			var el = en.target;
48			var tok = tokenFor(el);
49			if (!tok || seen[tok]) { return; }
50
51			if (en.isIntersecting && en.intersectionRatio >= 0.5) {
52				if (!el._fbTimer) {
53					el._fbTimer = setTimeout(function () {
54						el._fbTimer = null;
55						if (seen[tok]) { return; }
56						seen[tok] = 1;
57						pending[tok] = 1;
58						io.unobserve(el);
59						schedule();
60					}, 1000);
61				}
62			} else {
63				if (el._fbTimer) { clearTimeout(el._fbTimer); el._fbTimer = null; }
64			}
65		});
66	}, { threshold: [0, 0.5, 1] });
67
68	// Elige 50/50 qué variante mostrar en un contenedor A/B (la otra queda oculta).
69	function pickAbVariant(container) {
70		if (container._fbAb) { return; }
71		container._fbAb = 1;
72		var vs = container.querySelectorAll('.fbAds-ab-v');
73		if (vs.length < 2) { return; } // sin 2 variantes no hay nada que rotar
74		var showB = Math.random() < 0.5;
75		for (var i = 0; i < vs.length; i++) {
76			var isB = (vs[i].getAttribute('data-fbads-variant') === '1');
77			vs[i].hidden = showB ? !isB : isB;
78		}
79	}
80
81	function scan() {
82		// 1) resolver A/B: decidir qué variante se muestra (antes de observar)
83		var abs = document.querySelectorAll('.fbAds-banner.fbAds-ab');
84		for (var i = 0; i < abs.length; i++) { pickAbVariant(abs[i]); }
85
86		// 2) observar los elementos contables VISIBLES (no-A/B + la variante A/B mostrada)
87		var nodes = document.querySelectorAll('.fbAds-banner[data-fbads-id], .fbAds-ab-v[data-fbads-id]');
88		for (var j = 0; j < nodes.length; j++) {
89			var el = nodes[j];
90			if (el._fbObs || el.hidden) { continue; }
91			el._fbObs = 1;
92			io.observe(el);
93		}
94	}
95
96	if (document.readyState === 'loading') {
97		document.addEventListener('DOMContentLoaded', scan);
98	} else {
99		scan();
100	}
101
102	document.addEventListener('visibilitychange', function () {
103		if (document.visibilityState === 'hidden') { flush(); }
104	});
105	window.addEventListener('pagehide', flush);
106})();

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.