最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js如何實(shí)現(xiàn)元素曝光上報(bào)

 更新時(shí)間:2019年08月07日 15:34:29   作者:rbin  
這篇文章主要介紹了js如何實(shí)現(xiàn)元素曝光上報(bào),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

進(jìn)行數(shù)據(jù)上報(bào)的時(shí)候,經(jīng)常會(huì)遇到列表數(shù)據(jù)曝光上報(bào)的問(wèn)題,只對(duì)在當(dāng)前可視范圍內(nèi)的數(shù)據(jù)內(nèi)容進(jìn)行曝光上報(bào),而對(duì)于未在可視范圍內(nèi)的數(shù)據(jù)不進(jìn)行曝光上報(bào),等待用戶滾動(dòng)頁(yè)面或者區(qū)域使元素出現(xiàn)在可視范圍內(nèi)時(shí)才進(jìn)行曝光上報(bào)。

解決方案

目前針對(duì)此類問(wèn)題,主要有兩種解決方案。

方案一:監(jiān)聽頁(yè)面或者區(qū)域scroll事件,通過(guò)getBoundingClientRect接口取元素的位置與可視窗口進(jìn)行判斷。

function isElementInViewport(el) {
  var rect = el.getBoundingClientRect();

  var width_st = rect.width / 2,
    height_st = rect.height / 2;

  var innerHeight = window.innerHeight,
    innerWidth = window.innerWidth;


  if (  rect.top <=0 && rect.height > innerHeight 
    || rect.left <= 0 && rect.width > innerWidth
  ) {
    return rect.left * rect.right <= 0
      || rect.top * rect.bottom <= 0
  }

  return (
      rect.height > 0 
    && rect.width > 0 
    && ( ( rect.top >= 0 && rect.top <= innerHeight - height_st )
      || ( rect.bottom >= height_st && rect.bottom <= innerHeight ) )
    && ( ( rect.left >= 0 && rect.left <= innerWidth - width_st )
      || ( rect.right >= width_st && rect.right <= innerWidth ) )
  );
}

var nodes = document.querySelectorAll(".item")
function report(node) {
  // 上報(bào)的邏輯
}
window.onscroll = function() {
  nodes.forEach(node => {
    if( isElementInViewport(node) ) {
      report(node)
    }
  })
  
}

優(yōu)點(diǎn):兼容性好

缺點(diǎn):

  • 需要關(guān)注頁(yè)面或者區(qū)域的scroll事件
  • 頻繁的scroll事件,性能問(wèn)題

方案二:通過(guò) IntersectionObserver 監(jiān)聽元素是否處于可視范圍

function report(node) {
  // 上報(bào)的邏輯
}
var intersectionObserver = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if( entry.intersectionRatio > 0 ) {
      report(entry.target)
    }
  })
})
var nodes = document.querySelectorAll(".item")
nodes.forEach(node => {
  intersectionObserver.observe(node)
})

優(yōu)點(diǎn):

  • 無(wú)須關(guān)注 scroll
  • 回調(diào)是異步觸發(fā),不會(huì)頻繁觸發(fā),性能好

缺點(diǎn):兼容性不好?

實(shí)際上,針對(duì)兼容性問(wèn)題,w3c 官方提供了對(duì)應(yīng) polyfill, 因此intersectionObserver用于生產(chǎn)是可行的。

總結(jié)

筆者在實(shí)際運(yùn)用中,通過(guò) IntersectionObserver 封裝了一個(gè)簡(jiǎn)單的調(diào)用庫(kù),應(yīng)用于可視化埋點(diǎn) sdk 中,用于解決元素曝光問(wèn)題,如下

require('intersection-observer'); // polyfill

class Exposure {
  constructor(callback) {
    if (!callback || typeof callback !== 'function') {
      throw new Error("need callback or selector param")
      return
    }
    this.intersectionObserver = new IntersectionObserver((entries) => {
      entries.forEach(item => {
        if (item.intersectionRatio > 0) {
          if (item.target) {
            callback(item.target, item)
            this.intersectionObserver.unobserve(item.target)
          }
        }
      })
    });
  }

  observe(selector, ignoreExposured) {
    if (!this.intersectionObserver || !selector) {
      return
    }
    let nodes = []
    if( this.isDOM(selector) ) { // dom節(jié)點(diǎn)
      nodes = [selector]
    }else { // 選擇器
      nodes = document.querySelectorAll(selector)
    }
    if (!nodes.length) {
      return
    }
    nodes.forEach(node => {
      if (!ignoreExposured && node.__wg__tracker__exposured__) {
        return
      }
      node.__wg__tracker__exposured__ = true
      // 開始觀察
      this.intersectionObserver.observe(
        node
      );
    })
  }

  disconnect() {
    if (!this.intersectionObserver) {
      return
    }
    this.intersectionObserver.disconnect()
  }

  isDOM(obj) {
    if( !obj ) {
      return false
    }
    if( typeof HTMLElement === 'object' ) {
      return obj instanceof HTMLElement
    }
    if( typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string' ) {
      return true
    }
    return false
  }
}

export default Exposure

調(diào)用方法:

function report() {}
var exposurer = new Exposure((node) => {
  report(node)
})
exposurer.observe(".item)

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • javascript 構(gòu)建模塊化開發(fā)過(guò)程解析

    javascript 構(gòu)建模塊化開發(fā)過(guò)程解析

    這篇文章主要介紹了javascript 構(gòu)建模塊化開發(fā)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • JavaScript使用AOP編程思想實(shí)現(xiàn)監(jiān)聽HTTP請(qǐng)求

    JavaScript使用AOP編程思想實(shí)現(xiàn)監(jiān)聽HTTP請(qǐng)求

    這篇文章主要為大家詳細(xì)介紹了如何在JavaScript使用AOP編程思想實(shí)現(xiàn)監(jiān)聽HTTP請(qǐng)求,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • javascript之通用簡(jiǎn)單的table選項(xiàng)卡實(shí)現(xiàn)(二)

    javascript之通用簡(jiǎn)單的table選項(xiàng)卡實(shí)現(xiàn)(二)

    上篇中的選項(xiàng)卡存在這樣的問(wèn)題:把邏輯封裝在table.js中,不夠靈活,也就是說(shuō)如果某個(gè)選項(xiàng)卡是實(shí)現(xiàn)異步請(qǐng)求或者跳轉(zhuǎn),而非div的顯隱切換,那么就得修過(guò)table.js來(lái)達(dá)到目的,顯然不是我所需要的。
    2010-05-05
  • js 中的柯里化與反柯里化的基礎(chǔ)概念和用法

    js 中的柯里化與反柯里化的基礎(chǔ)概念和用法

    柯里化是將接受多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換成一系列只接受單個(gè)參數(shù)的函數(shù)的過(guò)程,而反柯里化是將柯里化函數(shù)轉(zhuǎn)換成接受多個(gè)參數(shù)的函數(shù)的過(guò)程,本文將帶大家理解 js 中的柯里化與反柯里化,需要的朋友可以參考下
    2023-07-07
  • 基于bootstrap的文件上傳控件bootstrap fileinput

    基于bootstrap的文件上傳控件bootstrap fileinput

    這篇文章主要為大家詳細(xì)介紹了基于bootstrap的文件上傳控件bootstrap fileinput,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • echarts圖例過(guò)多顯示問(wèn)題解決方案

    echarts圖例過(guò)多顯示問(wèn)題解決方案

    開發(fā)Echarts圖標(biāo)時(shí)經(jīng)常遇到數(shù)據(jù)量過(guò)多引起的圖例錯(cuò)亂,這個(gè)時(shí)候我們應(yīng)該如何處理?下面這篇文章主要給大家介紹了關(guān)于echarts圖例過(guò)多顯示問(wèn)題的解決方案,需要的朋友可以參考下
    2023-11-11
  • 如何用JS取得網(wǎng)址中的文件名

    如何用JS取得網(wǎng)址中的文件名

    如何用JS取得網(wǎng)址中的文件名...
    2006-08-08
  • javascript日期計(jì)算實(shí)例分析

    javascript日期計(jì)算實(shí)例分析

    這篇文章主要介紹了javascript日期計(jì)算,涉及javascript針對(duì)日期計(jì)算的相關(guān)技巧,這里需要注意索引的使用,需要的朋友可以參考下
    2015-06-06
  • sogou地圖API用法實(shí)例教程

    sogou地圖API用法實(shí)例教程

    這篇文章主要介紹了C# sogou地圖API用法,包括了各種常用屬性的用法實(shí)例,需要的朋友可以參考下
    2014-09-09
  • JS+css 圖片自動(dòng)縮放自適應(yīng)大小

    JS+css 圖片自動(dòng)縮放自適應(yīng)大小

    編輯器上傳的圖片太大了,把FF和IE撐的走形,所以希望圖片在某些頁(yè)面里要有固定大小,如果需要某個(gè)范圍,用getElementByname來(lái)設(shè)定,也是一個(gè)道理:
    2013-08-08

最新評(píng)論

廉江市| 襄垣县| 大足县| 府谷县| 三台县| 叶城县| 云阳县| 芦溪县| 南丰县| 饶河县| 诸城市| 安丘市| 孙吴县| 阿坝县| 太湖县| 六安市| 巍山| 宁陕县| 沂水县| 绥棱县| 涟源市| 通山县| 克拉玛依市| 武安市| 德州市| 屏南县| 资中县| 宝坻区| 龙口市| 滁州市| 含山县| 乐都县| 夹江县| 海门市| 荆门市| 辽阳市| 彩票| 东乡族自治县| 大港区| 林口县| 崇仁县|