let _adsPubId = ''; let hasAdxConfig = false let hasAdsConfig = false function weightedRandomSelect(items, weight_property) { // 构建累积权重数组 const cdf = items.reduce((acc, item) => { acc.push((acc.length > 0 ? acc[acc.length - 1] : 0) + item[weight_property]); return acc; }, []); // 生成一个介于 0 和 最大累积权重之间的随机数 const randomWeight = Math.random() * cdf[cdf.length - 1]; // 找到随机数落在累积权重数组中的位置 const selectedIndex = cdf.findIndex(cumulativeWeight => cumulativeWeight >= randomWeight); // 返回被选中的项 return items[selectedIndex]; } function swapItemsByExchangeWeight(origin) { // 1. 筛选出具有 exchange_target_id 和 exchange_weight 的项 const itemsWithExchange = origin.filter(item => item.exchange_target_id && item.exchange_weight ); if (!itemsWithExchange.length || itemsWithExchange.length < 2) return origin; // 2. 构建交换组 const groups = []; itemsWithExchange.forEach(item => { let list = [] if (item.isUsed) return itemsWithExchange.map(item2 => { if (item.exchange_target_id === item2.documentId) { item.isUsed = true list.push(item2) } if (item.documentId === item2.exchange_target_id) { item2.isUsed = true list.push(item) } }) groups.push(list) }); // 3. 根据概率随机选择要交换的项 groups.forEach((list, id) => { // 2. 计算每个项被选中的概率 let totalWeight = list.reduce((acc, item) => acc + item.exchange_weight, 0); // 3. 根据概率随机选择要交换的项 const randomIndex = Math.random() * totalWeight; let selectedItem = null; if (randomIndex <= list[0].exchange_weight) { return } else { selectedItem = list[0] } // 4. 找到对应的 exchange_target_id 的项 const targetItem = origin.find(item => item.documentId === selectedItem.exchange_target_id); // 5. 交换两个项的位置 const indexSelected = origin.indexOf(selectedItem); const indexTarget = origin.indexOf(targetItem); [origin[indexSelected], origin[indexTarget]] = [origin[indexTarget], origin[indexSelected]]; }); return origin; } function loadAdConfig(_adConfigList) { let swapAdConfigList = swapItemsByExchangeWeight(_adConfigList); let adConfigList = swapAdConfigList.map(item => { let poolList = item.poolListJson; if (poolList.length === 1) { let poolItem = poolList[0]; item.advertisingId = poolItem.advertisingId; item.advertisingKey = poolItem.advertisingKey; } else { let poolItem = weightedRandomSelect(poolList, 'weight'); item.advertisingId = poolItem.advertisingId; item.advertisingKey = poolItem.advertisingKey; } return item; }); const nativeAdType = ["adx", "ads"]; let bannerList = []; hasAdxConfig = adConfigList.some(ad => ad.type === "adx"); hasAdsConfig = adConfigList.some(ad => ad.type === "ads"); if (hasAdxConfig) { loadAdxScript(); } if (hasAdsConfig) { let pubId = adConfigList.find(ad => ad.type === "ads").advertisingKey; _adsPubId = pubId loadAdSenseScript(pubId); } adConfigList.forEach(ad => { if (nativeAdType.includes(ad.type)) { bannerList.push(ad); } const { advertisingKey, advertisingId, type } = ad; if (type === "ga") { loadGa(advertisingId); } else if (type === "interstitial" || type === "bottom") { loadOtherAd(advertisingKey, advertisingId, type); } }); loadBannerAds(bannerList); } function loadAdxScript() { const head = document.getElementsByTagName("head")[0]; const script = document.createElement("script"); script.src = "https://securepubads.g.doubleclick.net/tag/js/gpt.js"; script.async = true; head.appendChild(script); console.log('loadAdxScript'); } function loadAdSenseScript(pubId) { let allScripts = document.getElementsByTagName("script"); let adSenseScript = Array.from(allScripts).find(script => script.src.includes(`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${pubId}`)); if (adSenseScript) { return; } const head = document.getElementsByTagName("head")[0]; const script = document.createElement("script"); script.src = `https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${pubId}`; if (window.anchorOverlay && window.anchorOverlay === 'bottom') { script.setAttribute('data-overlays', 'bottom'); } script.async = true; head.appendChild(script); console.log('loadAdSenseScript'); } function loadBannerAds(bannerList) { const usedContainers = new Set(); // 用于记录已使用的广告容器 const adContainers = document.querySelectorAll('.ad-container'); // 获取所有广告容器 // 创建一个映射,将广告配置按容器索引进行索引 const adConfigMap = new Map(bannerList.map((adConfig, index) => [index, adConfig])); adContainers.forEach((container, index) => { const containerId = `ad-container-${index}`; // 如果容器还没有 id,则设置 id if (!container.id) { container.id = containerId; } // 检查广告容器是否已被使用 if (usedContainers.has(containerId)) { console.log(`Container ${containerId} is already in use.`); return; } // 获取对应的广告配置 const adConfig = adConfigMap.get(index); if (!adConfig) { console.log(`No ad config found for container at index ${index}.`); return; } // 标记广告容器为已使用 usedContainers.add(containerId); // 根据广告类型调用相应的加载方法 switch (adConfig.type) { case 'adx': observeAdContainer(container, () => loadAdx(adConfig, containerId, index)); break; case 'ads': observeAdContainer(container, () => loadAdSense(adConfig, containerId)); break; default: console.log(`Unknown ad type: ${adConfig.type}`); } }); if (hasAdxConfig) { initADXLoadEventListener(); } // 监听 ADX 广告加载情况 // 监听ads广告加载 } function observeAdContainer(container, callback) { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { callback(); observer.unobserve(container); // 确保广告只加载一次 } }); }, { threshold: 0.3 }); observer.observe(container); } function loadAdx(adConfig, containerId, index) { try { const { advertisingKey: Key, advertisingId: Id } = adConfig; const head = document.getElementsByTagName("head")[0]; const script = document.createElement("script"); let inner = ` window.googletag = window.googletag || { cmd: [] }; googletag.cmd.push(function () { googletag.defineSlot('${Key}', [300, 250], '${Id}').addService(googletag.pubads()).setTargeting('ad_label', 'native').setTargeting('ad_index', '${index}'); googletag.pubads().enableSingleRequest(); googletag.pubads().collapseEmptyDivs(); googletag.enableServices(); }); `; script.innerHTML = inner; head.appendChild(script); const container = document.getElementById(containerId); if (!container) { console.log(`Container ${containerId} not found.`); return; } container.setAttribute("style", "text-align:center; color:#787878;background-color: #e4e4e4; margin:20px 0px;"); let adTip = document.createElement("div"); adTip.innerHTML = "Advertisement"; container.appendChild(adTip); let adxDiv = document.createElement("div"); adxDiv.setAttribute("id", Id); adxDiv.setAttribute("style", "width: 100%; min-height: 250px; text-align: center;"); var adxScript = document.createElement("script"); adxScript.innerHTML = "googletag.cmd.push(function() { googletag.display('" + Id + "'); });"; adxDiv.appendChild(adxScript); container.appendChild(adxDiv); } catch (error) { console.error(error); } } function loadAdSense(adConfig, containerId) { console.log('load containerId', containerId); try { const { advertisingKey: Key, advertisingId: Id } = adConfig; const container = document.getElementById(containerId); if (!container) { console.log(`Container ${containerId} not found.`); return; } container.setAttribute("style", "width: 100%; min-height: 250px; text-align: center; background-color: #e4e4e4; margin: 20px auto; padding-bottom: 15px;"); const adDiv = document.createElement("div"); adDiv.style.textAlign = "center"; adDiv.style.color = "#787878"; adDiv.innerHTML = "Advertisement"; container.appendChild(adDiv); const adsIns = document.createElement("ins"); adsIns.className = "adsbygoogle"; adsIns.setAttribute("data-ad-client", Key); adsIns.setAttribute("data-ad-slot", Id); adsIns.setAttribute("data-ad-format", "auto"); adsIns.setAttribute("data-full-width-responsive", true); adsIns.setAttribute('style', "display:inline-block;width: 100%; min-height: 250px; text-align: center;") container.appendChild(adsIns); const adsScript = document.createElement("script"); adsScript.innerHTML = `(adsbygoogle = window.adsbygoogle || []).push({});`; container.appendChild(adsScript); } catch (error) { console.error(error); } } function initADXLoadEventListener() { console.log("init event adx listener"); window.googletag = window.googletag || { cmd: [] }; googletag.cmd.push(function () { googletag.pubads().addEventListener("slotRequested", function (event) { printEventMessage("slotRequested", event); }); googletag.pubads().addEventListener("slotResponseReceived", function (event) { printEventMessage("slotResponseReceived", event); }); googletag.pubads().addEventListener("slotOnload", function (event) { printEventMessage("slotOnload", event); }); googletag.pubads().addEventListener("slotRenderEnded", function (event) { if (event.isEmpty) { console.log("广告加载失败"); } printEventMessage("slotRenderEnded", event); }); googletag.pubads().addEventListener("impressionViewable", function (event) { printEventMessage("impressionViewable", event); }); }); } function printEventMessage(eventMessage, event) { const slotId = event.slot.getSlotElementId(); console.log("slotId:", slotId, "\nmessage:", eventMessage, "\nevent:", event); } function loadGa(value) { var head = document.getElementsByTagName("head")[0]; var scriptUrl = document.createElement("script"); scriptUrl.setAttribute("async", true); scriptUrl.src = `https://www.googletagmanager.com/gtag/js?id=${value}`; head.appendChild(scriptUrl); var scriptValue = document.createElement("script"); let inner = "window.dataLayer = window.dataLayer || []; \ function gtag(){dataLayer.push(arguments);} \ gtag('js', new Date()); \ gtag('config', '__VALUE__'); \ "; inner = inner.replace("__VALUE__", value); scriptValue.innerHTML = inner; head.appendChild(scriptValue); } function loadOtherAd(Key, Id, type) { try { var head = document.getElementsByTagName("head")[0]; var gptUrl = document.createElement("script"); gptUrl.setAttribute("async", true); gptUrl.src = "https://securepubads.g.doubleclick.net/tag/js/gpt.js"; head.appendChild(gptUrl); var script = document.createElement("script"); let script_inner = "window.googletag = window.googletag || {cmd: []}; \ googletag.cmd.push(function() { \ var slot = googletag.defineOutOfPageSlot('__KEY__', __ID__ ); \ if (slot) slot.addService(googletag.pubads()).setTargeting('ad_label', '__TYPE__'); \ googletag.enableServices();\ googletag.display(slot);\ });"; script_inner = script_inner.replace("__KEY__", Key).replace("__ID__", Id).replace("__TYPE__", type); script.innerHTML = script_inner; head.appendChild(script); } catch (error) { console.log(error); } }