H246802 / 30-days-challenge

30天每日打卡
4 stars 0 forks source link

day-26-自定义曝光组件 #26

Open H246802 opened 5 years ago

H246802 commented 5 years ago

写一个曝光组件 Expourse,实现当 dom 元素出现在浏览器窗口视野中时,执行回调函数,只执行一次。其中回调函数中的 this 代表 dom 元素

var expourse = new Expourse(node)
expourse.once(function() {
  console.log(this) // this 代表 node
  console.log('world') // node 曝光时执行,且只执行一次
})
H246802 commented 5 years ago

不考虑多次调用 once 方法

function Exposure(node) {
  this.element = node
}

Exposure.prototype.once = function (callback) {
  this._checkScroll = false
  this._callback = callback
  this.addEventListener()
}
Exposure.prototype.addEventListener = function () {
  window.onscroll = () => {
    // 判断是否滑动到位置
    if ((this.element.offsetTop - document.documentElement.clientHeight <= window.scrollY) && !this._checkScroll) {
        this._checkScroll = true
        this._callback.call(this.element)
    }
  }
}
let exposure = new Exposure(document.querySelector('#one'))
exposure.once(function () {
  console.log(this)
  console.log('world')
})
H246802 commented 5 years ago

考虑多次调用 once 方法


function Exposure(node) {
  this.element = node
}

Exposure.prototype.once = function (callback) {
  // 定义一个callback数组,每次当执行once方法时,
  // push回调
  // 添加一个是否以滚动的数组
  if (!this._callback) {
    this._callback = []
    this._checkScroll = []
    this._checkScroll.push(false)
    this._callback.push(callback)
  } else {
    this._checkScroll.push(false)
    this._callback.push(callback)
  }
  this.addEventListener()
//     callback.call(this.element)
}
Exposure.prototype.addEventListener = function () {
  window.onscroll = () => {
    for (let i = 0; i < this._callback.length; ++i) {
      if ((this.element.offsetTop - document.documentElement.clientHeight <= window.scrollY) && !this._checkScroll[i]) {
        this._checkScroll[i] = true
        this._callback[i].call(this.element)
      }
    }
  }
}
let exposure = new Exposure(document.getElementById('one'))
exposure.once(function () {
  console.log(this)
  console.log('world')
})