實現一個hoverDelay延遲hover
author: @TiffanysBear
需求背景
經常在頁面開發中,需要使用hover事件來觸發相應的網絡請求或頁面DOM元素顯示切換,需要考慮的問題就有了:
- hover動作非常快,如果一hover就請求,會造成多余請求的浪費,造成后端接口不必要的壓力
- 如何判斷這個用戶hover是想做一定的操作,而不是鼠標誤觸
- 構造這個hover延遲的時候,怎樣封裝才能通用使用
先來看一下效果演示:
See the Pen Vue.js | Mouseover & Mouseleave by AAA_TTT ( @AAA_TTT) on CodePen.問題思考
基於上述的問題,思考是如下:
- 當用戶hover停留在某一DOM元素上一定時長時,比如500ms,才認為這個用戶是實際想要做某種操作,這時候在實際的進行相應的網絡請求或頁面DOM元素顯示切換
- 如果在500ms之前就移開,就算是用戶誤觸誤滑,不做任何處理
- 構造hover通用封裝時,采用jQuery的插件開發的方式,形成通用的解決方案
代碼封裝
基於jQuery的插件系統,實現的hoverDelay插件方法;在每次事件之前,清空所有的計時器,重新設置延時定時器,則進行相應操作。
/**
* @file: 鼠標滑動延遲執行的JQUERY擴展方法
* @author: TiffanysBear
*
*/
$.fn.hoverDelay = function (options) {
var defaults = {
hoverDuring: 200,
outDuring: 200,
hoverEvent: function () {
$.noop();
},
outEvent: function () {
$.noop();
}
};
var sets = $.extend(defaults, options || {});
var hoverTimer;
var outTimer;
return $(this).each(function () {
$(this).hover(function () {
clearTimeout(outTimer);
hoverTimer = setTimeout(sets.hoverEvent, sets.hoverDuring);
}, function () {
clearTimeout(hoverTimer);
outTimer = setTimeout(sets.outEvent, sets.outDuring);
});
});
};
代碼使用
因為該方法是放在jQuery的原型方法上,因此所有jQuery對象都有這個方法可以使用。
$(this).hoverDelay({
hoverDuring: 500,
outDuring: 300,
hoverEvent: function () {
},
outEvent: function () {
}
});
后續思考
類似與Vue這種類似於MVVM框架的項目應該如何做hoverDelay呢?原理也是一致的;但是在細節的處理上有些不同,通過Vue綁定的 mouseover
、mouseleave
對定時器進行設置和清理也能實現需求。
html結構:
.<div id="mouse">
<a
v-on:mouseover="mouseover"
v-on:mouseleave="mouseleave">
{{message}}
</a>
</div>
css樣式:
body {
background: #333;
#mouse {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
width: 280px;
height: 50px;
margin: 0 auto;
line-height: 50px;
text-align: center;
color: #fff;
background: #007db9;
a {
display: block;
width: 100%;
height: 100%;
cursor: pointer;
}
}
}
JS代碼:
new Vue({
el: '#mouse',
data: {
message: 'Hover Me!' ,
timer: null,
hoverEnterTime: 500,
hoverLeaveTime: 300
},
methods: {
mouseover: function(){
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.message = 'Good!'
}, this.hoverEnterTime);
},
mouseleave: function(){
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.message = 'Hover Me!!'
}, this.hoverEnterTime);
}
}
})
See the Pen
Vue.js | Mouseover & Mouseleave by AAA_TTT (
@AAA_TTT) on
CodePen.