實(shí)現(xiàn)一個(gè)hoverDelay延遲hover
author: @TiffanysBear
需求背景
經(jīng)常在頁(yè)面開(kāi)發(fā)中纲堵,需要使用hover事件來(lái)觸發(fā)相應(yīng)的網(wǎng)絡(luò)請(qǐng)求或頁(yè)面DOM元素顯示切換壁酬,需要考慮的問(wèn)題就有了:
- hover動(dòng)作非常快蓖宦,如果一hover就請(qǐng)求,會(huì)造成多余請(qǐng)求的浪費(fèi),造成后端接口不必要的壓力
- 如何判斷這個(gè)用戶hover是想做一定的操作唐瀑,而不是鼠標(biāo)誤觸
- 構(gòu)造這個(gè)hover延遲的時(shí)候,怎樣封裝才能通用使用
先來(lái)看一下效果演示:
<iframe height="257" style="width: 100%;" scrolling="no" title="Vue.js | Mouseover & Mouseleave" src="http://codepen.io/AAA_TTT/embed/VorrpN/?height=257&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true">
See the Pen <a >Vue.js | Mouseover & Mouseleave</a> by AAA_TTT
(<a >@AAA_TTT</a>) on <a >CodePen</a>.
</iframe>
問(wèn)題思考
基于上述的問(wèn)題插爹,思考是如下:
- 當(dāng)用戶hover停留在某一DOM元素上一定時(shí)長(zhǎng)時(shí)哄辣,比如500ms,才認(rèn)為這個(gè)用戶是實(shí)際想要做某種操作递惋,這時(shí)候在實(shí)際的進(jìn)行相應(yīng)的網(wǎng)絡(luò)請(qǐng)求或頁(yè)面DOM元素顯示切換
- 如果在500ms之前就移開(kāi)柔滔,就算是用戶誤觸誤滑,不做任何處理
- 構(gòu)造hover通用封裝時(shí)萍虽,采用jQuery的插件開(kāi)發(fā)的方式睛廊,形成通用的解決方案
代碼封裝
基于jQuery的插件系統(tǒng),實(shí)現(xiàn)的hoverDelay插件方法杉编;在每次事件之前超全,清空所有的計(jì)時(shí)器,重新設(shè)置延時(shí)定時(shí)器邓馒,則進(jìn)行相應(yīng)操作嘶朱。
/**
* @file: 鼠標(biāo)滑動(dòng)延遲執(zhí)行的JQUERY擴(kuò)展方法
* @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);
});
});
};
代碼使用
因?yàn)樵摲椒ㄊ欠旁趈Query的原型方法上,因此所有jQuery對(duì)象都有這個(gè)方法可以使用光酣。
$(this).hoverDelay({
hoverDuring: 500,
outDuring: 300,
hoverEvent: function () {
},
outEvent: function () {
}
});
后續(xù)思考
類(lèi)似與Vue這種類(lèi)似于MVVM框架的項(xiàng)目應(yīng)該如何做hoverDelay呢疏遏?原理也是一致的;但是在細(xì)節(jié)的處理上有些不同,通過(guò)Vue綁定的 mouseover
财异、mouseleave
對(duì)定時(shí)器進(jìn)行設(shè)置和清理也能實(shí)現(xiàn)需求倘零。
html結(jié)構(gòu):
.<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);
}
}
})
<iframe height="265" style="width: 100%;" scrolling="no" title="Vue.js | Mouseover & Mouseleave" src="https://codepen.io/AAA_TTT/embed/VorrpN/?height=265&theme-id=0&default-tab=js" frameborder="no" allowtransparency="true" allowfullscreen="true">
See the Pen <a >Vue.js | Mouseover & Mouseleave</a> by AAA_TTT
(<a >@AAA_TTT</a>) on <a >CodePen</a>.
</iframe>