鍍金池/ 問答/網(wǎng)絡(luò)安全  HTML/ 如何合理節(jié)流onmousemove事件?

如何合理節(jié)流onmousemove事件?

    //鼠標(biāo)點(diǎn)擊開始
    center[0].onmousedown = function () {
    
        docMove();

        //數(shù)據(jù)釋放
        document.onmouseup = function () {
            document.onmousemove = null;
            document.onmouseup = null;
        };
    };

    function docMove() {
        document.onmousemove = function (e) {
            var e     = e || window.event;
            var newX  = e.clientX;
            
           //通過newX動(dòng)態(tài)設(shè)置元素css來達(dá)到改變位置的效果
           
            //阻止冒泡
            e.stopPropagation();
        };
    }

問題:如何通過setTimeout達(dá)到函數(shù)節(jié)流,提升性能?
PS:目前事件執(zhí)行還有一個(gè)小問題,就是在移動(dòng)元素的過程中會(huì)間接性出現(xiàn)鼠標(biāo)已經(jīng)釋放但onmousemove 并未失效的問題,(實(shí)際觀感就是鼠標(biāo)左鍵已經(jīng)釋放,但是元素還會(huì)跟著鼠標(biāo)移動(dòng))

回答
編輯回答
小眼睛

你也聽到通過 setTimeout 進(jìn)行節(jié)流。那么你應(yīng)該明白節(jié)流的原理?將事件綁定,然后將事件取消,又綁定。即定義某個(gè)操作,然后在 setTimeout 內(nèi)部刪除,然后設(shè)置新的開始 setTimeout,在新的開始后又重新綁定結(jié)束刪除,遞歸就行。具體根據(jù)需求完成罷。

2017年5月3日 06:24
編輯回答
魚梓

函數(shù)節(jié)流:

var t = null
document.addEventListener('mousemove', () => {
    if (t === null) {
        t = setTimeout(() => {
            console.log('執(zhí)行')
            t = null
        }, 16)
    }
}, false)

為何是 16ms 間隔請參考:https://www.cnblogs.com/liuha...

鼠標(biāo)釋放元素依然移動(dòng):可以在 onmousedown 時(shí)開啟元素可移動(dòng)的開關(guān),onmouseup 時(shí)關(guān)閉元素可移動(dòng)的開關(guān),onmousemove 時(shí)判斷開關(guān)的狀態(tài)決定是否執(zhí)行元素移動(dòng)的回調(diào),開關(guān)即為一個(gè)自己聲明的布爾型的變量。

var flag = false
document.addEventListener('mousedown', () => {
    flag = true
}, false)
document.addEventListener('mousemove', () => {
    if (flag) console.log('執(zhí)行元素移動(dòng)')
}, false)
document.addEventListener('mouseup', () => {
    flag = false
}, false)
2017年1月5日 18:01
編輯回答
巫婆

實(shí)現(xiàn)思路就是判斷觸發(fā)事件的時(shí)間和上次觸發(fā)事件的時(shí)間間隔超過設(shè)定值才觸發(fā)新的處理函數(shù)。

建議使用loadsh等類庫現(xiàn)成的節(jié)流構(gòu)造函數(shù)即可,自己實(shí)現(xiàn)當(dāng)然也行。

2017年4月5日 22:35
編輯回答
影魅
dom.onmousemove=function(){
     if (this.time && Date.now() - this.time < 50) return
     this.time = Date.now()
    // you code
}

如果在移動(dòng)元素的回調(diào)里節(jié)流,會(huì)導(dǎo)致移動(dòng)卡卡的.最好不要高于16(1000/60,顯示器一般刷新率是60幀/秒)

附贈(zèng)一個(gè)簡單的拖拽吧

  let box = document.querySelector('.box')
  document.onmousedown = function (e) {
    let down = false
    if (e.target === box) {
      down = true
      e.target.x = e.offsetX
      e.target.y = e.offsetY
    }
    document.onmousemove = function (e) {
      if (!down) return
      if (this.time && (Date.now() - this.time) < 16) return
      this.time = Date.now()
      box.style.transform = `translate3d(${e.clientX - box.x}px,${e.clientY - box.y}px,0)`
    }
    document.onmouseup = clear
  }

  function clear() {
    document.onmouseup = document.onmousemove = null
  }
2017年8月26日 23:03