123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- /**
- * 创建广告
- * config 参数说明
- * @param {string[]} ad_id 广告id
- * @param {string} ad_type 广告类型 1:视频 2:图片
- * @param {string} ad_pos 广告位置
- * @param {string[]} ad_size 广告尺寸
- * @param {string} ad_text 广告文案
- * @param {string[]} ad_url 广告链接
- * @param {string[]} ad_cover 广告图片
- */
- document.addEventListener('DOMContentLoaded', function () {
- const agreement =
- location.origin === 'http://' ? 'http:' : location.origin === 'https://' ? 'https:' : 'http://'
- const base = agreement + '10.30.160.129:8082/'
- /**
- * 广告初始化
- * @param config 广告配置
- * @returns
- */
- function ad_init(config = {}) {
- // 启动上报
- const slots = config.slots || []
- const D = new Date()
- const dateTime = D.getTime()
- for (let i = 0; i < slots.length; i++) {
- const v = slots[i]
- if (!v.creativesList || !v.creativesList.length) continue
- // 获取对应广告位置
- const ad_pos = document.querySelector('#sxtv-ad-' + v.slotId)
- if (!ad_pos) {
- console.error('广告位置不存在:#sxtv-ad-' + v.slotId)
- continue
- }
- const gg = document.createElement('div')
- gg.innerHTML =
- '<svg t="1734493782806" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9775" width="32" height="32"><path d="M560.88 658.8h69.68v15.44h-69.68z" p-id="9776" fill="#515151"></path><path d="M698.24 451.44V200h-46.56v251.44H372.32V200h-46.56v251.44H186V824h651.92V451.44zM505.12 600H396.16v90.72L352 700.08v-33.92l8-2.4V575.2h54.24l-1.84-8.8h45.84l1.68 8.8h44.88z m162.72 96.48H524.4v-60h143.44z m5.36-64.48H518.88v-23.36h61.12v-11.28h-22.16l-2.88 8.48H520V582.4h8.72l5.52-13.76H568l-2.32 6.64h14.32v-8h38.64v8h49.04v22h-49.04v11.36h54.56z" p-id="9777" fill="#515151"></path></svg>'
- gg.style.position = 'absolute'
- gg.style.top = 0
- gg.style.right = 3
- gg.style.zIndex = 999999
- // 判定当前时间是否在creativesList的时间内
- const ele = document.createElement('div')
- ele.style.position = 'relative'
- ele.appendChild(gg)
- for (let o = 0; o < v.creativesList.length; o++) {
- const item = v.creativesList[o]
- const start = new Date(item.startDate + ' 00:00:00').getTime()
- const end = new Date(item.endDate + ' 23:59:59').getTime()
- // 判断变量是否数组
- if (dateTime < start || dateTime > end || !Array.isArray(item.stuffsList)) continue
- // 获取广告类型 1 轮播 2 交替 3 单项
- const showType = item.showType
- let e =
- showType === 1
- ? generateCarouselAd(item, D, v.slotId, v.width || 0, v.height || 0)
- : generateAlternateAd(item, D, v.slotId, v.width || 0, v.height || 0)
- if (e == -1) break
- ele.appendChild(e)
- ele.style.width = '100%'
- ele.style.height = '100%'
- }
- ad_pos.style.width = (v.width || 0) + 'px'
- ad_pos.style.height = (v.height || 0) + 'px'
- ad_pos.style.border = 'none'
- ad_pos.style.overflow = 'hidden'
- ad_pos.appendChild(ele)
- }
- }
- // 生成轮播广告
- const generateCarouselAd = function (generateCarousel = {}, D, slotId, width, height) {
- const week = D.getDay() === 0 ? 6 : D.getDay() - 1
- const timeInterval = (generateCarousel.timeInterval || '')
- .slice(week * 24, week * 24 + 24)
- .split('')
- const H = D.getHours()
- if (generateCarousel.intervalType === 2 && timeInterval[H] == 0) return -1
- const T = (generateCarousel.showIntervalTime || 5) * 1000
- return createCarousel(generateCarousel.stuffsList, T, slotId, width, height)
- }
- // 生成交替广告
- const generateAlternateAd = function (generateAlternate = {}, D, slotId, width, height) {
- const week = D.getDay() === 0 ? 6 : D.getDay() - 1
- const timeInterval = (generateAlternate.timeInterval || '')
- .slice(week * 24, week * 24 + 24)
- .split('')
- const H = D.getHours()
- if (generateAlternate.intervalType === 2 && timeInterval[H] == 0) return -1
- const stuff =
- generateAlternate.stuffsList[
- Math.floor((H * 60 + D.getMinutes()) / (generateAlternate.showIntervalTime || 5)) %
- generateAlternate.stuffsList.length
- ]
- if (!stuff) return -1
- const fileType = stuff.addr.split('.').pop()
- // fileType是否是图片类型
- if (fileType === 'jpg' || fileType === 'png' || fileType === 'gif') {
- const son_ele = document.createElement('img')
- son_ele.src = stuff.addr
- son_ele.style.width = width + 'px'
- son_ele.style.height = height + 'px'
- son_ele.onload = () => {
- const uuid = localStorage.getItem('ad_id')
- fetch(`${base}ad/show?uuid=${uuid}&stuffId=${stuff.stuffId}&slotId=${slotId}`).then((res) =>
- res.text(),
- )
- }
- son_ele.addEventListener('click', () => {
- const uuid = localStorage.getItem('ad_id')
- // 点击广告
- fetch(`${base}ad/click?uuid=${uuid}&stuffId=${stuff.stuffId}&slotId=${slotId}`)
- .then((res) => res.text())
- .then(() => {
- window.open(stuff.landingPage)
- })
- })
- return son_ele
- }
- const son_ele = document.createElement('video')
- son_ele.setAttribute('loop', 'loop')
- son_ele.setAttribute('autoplay', 'autoplay')
- son_ele.setAttribute('muted', 'muted')
- son_ele.src = stuff.addr
- son_ele.style.width = '100%'
- son_ele.style.height = '100%'
- // 视频加载允许播放的回调
- son_ele.oncanplay = () => {
- son_ele.play()
- const uuid = localStorage.getItem('ad_id')
- fetch(`${base}ad/show?uuid=${uuid}&stuffId=${src.stuffId}&slotId=${slotId}`).then((res) =>
- res.text(),
- )
- }
- son_ele.addEventListener('click', () => {
- const uuid = localStorage.getItem('ad_id')
- // 点击广告
- fetch(`${base}ad/click?uuid=${uuid}&stuffId=${stuff.stuffId}&slotId=${slotId}`)
- .then((res) => res.text())
- .then(() => {
- window.open(stuff.landingPage)
- })
- })
- // 对body添加一次性点击事件
- const play = () => {
- son_ele.play()
- // 移除点击
- document.body.removeEventListener('click', play)
- }
- document.body.addEventListener('click', play)
- return son_ele
- }
- function generateBrowserFingerprint() {
- return new Promise((resolve, reject) => {
- // 在这里执行获取指纹的操作,例如使用Canvas、WebGL等方法
- // 然后将生成的指纹字符串作为参数传递给resolve函数
- // 获取浏览器信息
- const browserInfo = `${navigator.userAgent} ${window.screen.width}x${window.screen.height}`
- // 获取时区偏移量
- const timezoneOffset = Intl.DateTimeFormat().resolvedOptions().timeZone
- // 在这里处理获取到的指纹信息
- const canvasFingerprint = getCanvasFingerprint()
- const webglFingerprint = getWebglFingerprint()
- // 将所有信息组合成一个字符串
- const fingerprintStr = `${browserInfo}|${timezoneOffset}|${canvasFingerprint}|${webglFingerprint}`
- // 使用createHash生成哈希值
- createHash(fingerprintStr)
- .then((hash) => {
- resolve(hash)
- })
- .catch((error) => {
- reject(error)
- })
- })
- }
- // Canvas指纹获取函数
- function getCanvasFingerprint() {
- const canvas = document.createElement('canvas')
- const ctx = canvas.getContext('2d')
- if (!ctx) return ''
- // 绘制一些内容
- ctx.fillStyle = '#f60'
- ctx.fillRect(0, 0, 16, 16)
- ctx.fillStyle = '#069'
- ctx.font = '11pt Arial'
- ctx.fillText('Cwm fjord!!', 4, 10)
- ctx.fillStyle = 'rgba(102, 204, 0, 0.7)'
- ctx.fillText('Cwm fjord!!', 5, 11)
- ctx.scale(2, 2)
- ctx.fillStyle = '#fff'
- ctx.font = '24pt Arial'
- ctx.fillText('Cwm fjord!!', 10, 25)
- ctx.fillStyle = 'rgba(102, 204, 0, 0.7)'
- ctx.fillText('Cwm fjord!!', 10, 25)
- const data = canvas.toDataURL()
- return data.replace(/data:image\/png;base64,/, '')
- }
- // WebGL指纹获取函数
- function getWebglFingerprint() {
- const canvas = document.createElement('canvas')
- const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
- if (!gl) return ''
- const extensions = gl.getSupportedExtensions()
- if (!extensions) return ''
- const extStr = extensions.join(',')
- const rendererInfo = gl.getParameter(gl.RENDERER) + '/' + gl.getParameter(gl.VENDOR)
- return rendererInfo + extStr
- }
- function createHash(str) {
- if (!crypto || !crypto.subtle || !crypto.subtle.digest || !TextEncoder) {
- console.error('浏览器不支持创建哈希值')
- return Promise.reject()
- }
- // 将字符串转换为 Uint8Array
- const encoder = new TextEncoder()
- const data = encoder.encode(str)
- // 使用 SubtleCrypto API 计算 SHA-256 摘要
- return new Promise((resolve, reject) => {
- crypto.subtle
- .digest('SHA-256', data)
- .then((hashBuffer) => {
- // 将 ArrayBuffer 转换为十六进制字符串
- const hashArray = Array.from(new Uint8Array(hashBuffer))
- const hashHex = hashArray.map((byte) => byte.toString(16).padStart(2, '0')).join('')
- resolve(hashHex)
- })
- .catch((error) => {
- reject(error)
- })
- })
- }
- // 轮播
- function createCarousel(images, interval, slotId, width, height) {
- // 创建轮播图容器
- const carouselContainer = document.createElement('div')
- carouselContainer.style = `
- position: relative;
- width: 100%;
- height: 100%;
- margin: auto;
- overflow: hidden;
- `
- // 创建图片容器
- const imagesContainer = document.createElement('div')
- imagesContainer.style = `
- width: ${images.length * width}px;
- height: ${height}px;
- display: flex;
- transition: transform 0.5s ease;
- `
- // 创建指示器容器
- const indicatorsContainer = document.createElement('div')
- indicatorsContainer.style = `
- position: absolute;
- bottom: 10px;
- left: 50%;
- margin-right: 5px;
- transform: translateX(-50%);
- `
- // 添加图片到容器
- images.forEach((src, index) => {
- const img = document.createElement('img')
- img.src = src.addr
- img.alt = `Image ${index + 1}`
- img.style = `
- flex: 1;
- width: ${width}px;
- height: 100%;
- `
- img.addEventListener('click', () => {
- const uuid = localStorage.getItem('ad_id')
- // 点击广告
- fetch(`${base}ad/click?uuid=${uuid}&stuffId=${src.stuffId}&slotId=${slotId}`)
- .then((res) => res.text())
- .then(() => {
- window.open(src.landingPage)
- })
- })
- // 图片加载完成
- img.onload = () => {
- const uuid = localStorage.getItem('ad_id')
- fetch(`${base}ad/show?uuid=${uuid}&stuffId=${src.stuffId}&slotId=${slotId}`).then((res) =>
- res.text(),
- )
- }
- imagesContainer.appendChild(img)
- // 添加指示器
- const indicator = document.createElement('button')
- indicator.style = `
- border: none;
- background-color: #fff;
- cursor: pointer;
- padding: 5px;
- border-radius: 50%;
- width: 10px;
- height: 10px;
- margin-right: 5px;
- display: inline-block;
- `
- if (index !== 0) indicator.style.backgroundColor = '#ccc'
- indicator.dataset.target = index
- indicatorsContainer.appendChild(indicator)
- })
- // 将图片容器和指示器容器添加到轮播图容器
- carouselContainer.appendChild(imagesContainer)
- carouselContainer.appendChild(indicatorsContainer)
- // 设置轮播图的切换逻辑
- let currentImageIndex = 0
- const maxImages = images.length
- function showImage(index) {
- // 更新图片位置
- imagesContainer.style.transform = `translateX(-${index * width}px)`
- // 更新指示器
- indicatorsContainer.querySelectorAll('button').forEach((btn, i) => {
- btn.style.backgroundColor = i === index ? '#000' : '#ccc'
- })
- currentImageIndex = index
- }
- function nextImage() {
- currentImageIndex = (currentImageIndex + 1) % maxImages
- showImage(currentImageIndex)
- }
- // 为指示器添加点击事件
- indicatorsContainer.addEventListener('click', function (e) {
- if (e.target.tagName === 'BUTTON') {
- const targetIndex = parseInt(e.target.dataset.target)
- showImage(targetIndex)
- }
- })
- // 自动播放轮播图
- let intervalId = setInterval(nextImage, interval)
- // 可选:鼠标悬停时停止自动播放
- carouselContainer.addEventListener('mouseenter', () => {
- clearInterval(intervalId)
- })
- carouselContainer.addEventListener('mouseleave', () => {
- intervalId = setInterval(nextImage, interval)
- })
- return carouselContainer
- }
- // 轮播End
- const script = document.querySelector('#sxtv-ad-id')
- const CFG = agreement + 'cxzx.smcic.net/ad/catalog/' + script.getAttribute('ad_id') + '.json'
- try {
- fetch(CFG + '?' + Date.now())
- .then((res) => res.json())
- .then((res) => {
- const data = res
- // 广告sdk
- if (localStorage.getItem('ad_id')) {
- ad_init(data)
- return
- }
- // 生成并输出浏览器指纹
- generateBrowserFingerprint().then((ad_id) => {
- localStorage.setItem('ad_id', ad_id + '')
- ad_init(data)
- })
- })
- } catch (error) {
- console.error(error)
- }
- })
|