1. 程式人生 > 其它 >onchange事件實現編輯_[JS基礎] 15 - 節流 防抖 / Event Bus / new實現

onchange事件實現編輯_[JS基礎] 15 - 節流 防抖 / Event Bus / new實現

技術標籤:onchange事件實現編輯

b797ada79f6dba681d16328e92b0d9ab.png

持續補充

1. 節流 throttle

規定在一個單位時間內, 只能觸發一次函式。

// 規定在一個單位時間內, 只能觸發一次函式。
// 如果這個單位時間內觸發多次函式, 只有一次生效。

const throttle = (fn, time = 500) => {
  // 可以執行的標識, 閉包儲存該標識
  let flag = true
  
  // 傳遞引數
  return (...args) => {
    // 不許執行, 結束
    if (flag === false) {
      return
    }
    // 設定不許執行
    flag = false
    setTimeout(() => {
      // 回撥 並用到這些引數
      fn.apply(this, args)
      flag = true
    }, time)
  }
}

2. 防抖 debounce 圖片懶載入是防抖的應用。

在事件被觸發n秒後再執行回撥,如果在這n秒內又被觸發,則重新計時。

// 在事件被觸發n秒後再執行回撥,如果在這n秒內又被觸發,則重新計時。
const debounce = (fn, limit = 500) => {
  // 執行標識
  let timer = null

  return (...args) => {
    // 清理閉包中的, 重新開始
    clearTimeout(timer)

    // 執行標識 放到閉包中
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, limit)
  }
}

參考: 節流防抖圖

3 - Event Bus 實現

訂閱 (註冊 ) 和 釋出 (執行) 模式

ae88423637dcd9b52d27938b5cf6c264.png
  • on 可以多次註冊 事件 對應的回撥函式
  • once 只可以呼叫一次
  • emit 執行該回調 => 如果是on 就是 迴圈輸出,如果是once 就是隻輸出一次
  • removeListener 刪除掉該事件
<script>
  function EventBus () {
    this.eventObject = {}
    // this.eventObject.event = [callback, callback, ....]
  }

  // 可多次註冊
  EventBus.prototype.on = function (type, callback) {
    if (typeof type !== 'string' || typeof callback !== 'function') {
      return
    }

    // 沒有該事件則建立, 有則將回調函式push進去
    if (this.eventObject[type] && this.eventObject[type].length !== 0) {
      this.eventObject[type].push(callback)
    } else {
      this.eventObject[type] = [callback]
    }
  }

  // 只註冊一次
  EventBus.prototype.once = function (type, callback) {
    if (typeof type !== 'string' || typeof callback !== 'function') {
      return
    }
    this.eventObject[type] = [callback]
  }

  // 呼叫該執行
  EventBus.prototype.emit = function (type, ...args) {
    const eventList = this.eventObject[type]
    if (typeof type !== 'string' || !eventList || eventList && eventList.length === 0) {
      return
    }

    // eventList = [callback, callback, ....] 執行
    eventList.forEach(callback => {
      if (args.length > 0) {
        callback.apply(this, args)
      } else {
        callback.call(this)
      }
    });
  }

  // 刪除該事件
  EventBus.prototype.removeListener = function (type) {
    delete this.eventObject[type]
  }

  EventBus.prototype.getEventObject = function () {
    return this.eventObject
  }


  const eventInstance = new EventBus()

  eventInstance.on('onClick', function () {
    // this, 可指向 到 EventBus
    console.log('1', this) // EventBus {eventObject: {…}}
  })

  eventInstance.on('onClick', function (...params) {
    console.log('2', params) // [1, 2, 3]
  })

  eventInstance.on('onClick', function (params1, params2, params3) {
    console.log('3', params1, params2, params3)
  })

  eventInstance.once('onChange', function (params) {
    console.log('1', params)
  })

  console.log(eventInstance.getEventObject())
  eventInstance.removeListener('onChange')
  console.log(eventInstance.getEventObject())

  eventInstance.emit('onClick', 1, 2, 3)
</script>

4 - new 實現

function Parent (surname, givename) { // 建構函式
  this.surname = surname
  this.givename = givename
}

Parent.prototype = {
  constructor: Parent, // 我是來自Parent的方法
  getParentSurName: function () { console.log(this.surname, this.givename) }
}



function NEW (CLASS) {
  // 1. 建立個空物件
  var obj = {}

  // 2. 我來自誰的建立  建構函式是 CLASS
  obj.constructor = CLASS

  // 3. 指標指向公共方法
  obj.__proto__ = CLASS.prototype

  // 4. 私有屬性也需要掛載到obj上面
  // Array.prototype.slice.call(arguments, 1) 作用是擷取傳入引數, 只留下a,b,c
  // NEW (CLASS, a, b, c) => args[a, b, c]
  const args = Array.prototype.slice.call(arguments, 1)

  // 執行建構函式,通過apply傳入this和引數
  // CLASS 需要傳入 args 引數,  apply是將環境繫結到 obj 這個環境內。
  CLASS.apply(obj, args)
  return obj
}