需求背景
D3 tooltip內容過多,需要展示滾動條。鼠標離開定位後,立刻觸發mouseout,此時tooltip會隱藏。但是,需求是不能隱藏。那麼久從離開到隱藏之間,存在一定時間的隱藏。
用delay實現
# 全局變量控制
cancelDealHandler(){
if(something){ //取消
cancle = true;
}else {
cancle = false;
}
}
line.on('mouseover',() => {
//觸發tooltip顯示
showTip();
}).on('mouseout',() => {
_.delay(() => {
if(cancle){ //取消隱藏,全局變量控制
return;
}
hideTip();
},3000);
})
;
上述方法實現總結
- 確實能做到tip顯示控制
- 不過,存在嚴重缺陷,小夥伴你知道嗎?
我們查看下delay源碼
/**
* Invokes `func` after `wait` milliseconds. Any additional arguments are
* provided to `func` when it's invoked.
*
* @since 0.1.0
* @category Function
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
* @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
* delay(text => console.log(text), 1000, 'later')
* // => Logs 'later' after one second.
*/
function delay(func, wait, ...args) {
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
return setTimeout(func, wait || 0, ...args)
}
export default delay
哦哦,原來,底層使用setTimeout!!!
上述方法的問題:
- 沒調用一次delay,觸發一次setTimeout
- 大量的mouseout,那麼久會產生很多setTimout
- 過多的setTimout,會進入排隊等待執行,
- 當某次代碼執行到hideTip()前,cancel= true,但是此時依舊會隱藏tip.
- 沒有及時清空timer,雖然只會執行一次
改進
# 全局變量控制
cancelDealHandler(){
if(something){ //取消
clearTimeout(delayTimer);
}else {
hideTip();
}
}
line.on('mouseover',() => {
//觸發tooltip顯示
clearTimeout(delayTimer);
showTip();
}).on('mouseout',() => {
clearTimeout(delayTimer);
delayTimer = _.delay(() => {
hideTip();
},3000);
})
;
歡迎關注我們【前端漫漫】,瞭解最新文章動態聯繫郵箱:[email protected]