实现一个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.

实现一个hoverDelay延迟hover的更多相关文章

  1. jquery实现一个标签图标hover到上面的时候显示tooltip

    设计图: 解决思路:1.在thumbnailbox.js这个插件中加入tags弹出框显示的内容,一开始让这些内容display:none; 然后再用css画出来一个三角形 实现方法: 知识点:Jque ...

  2. 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

    [源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...

  3. JS实现类似QQ好友头像hover时显示资料卡的效果

    一.应用场景 鼠标hover弹出div,并且鼠标离开后不能马上隐藏,因为这个div上还有功能入口.比如: 鼠标经过好友列表中的好友头像时显示资料卡的效果 hover时显示二维码 二.实现 用如下这样一 ...

  4. 移动端:active,:hover无法很好触发动画的解决方案

    移动端:active,:hover无法很好触发动画的解决方案 1:问题环境: 用css3定义了一个动画,使用:hover伪类调用动画时在移动端不能很好的进行动画. 2:解决方案: 定义一个open类, ...

  5. 实现了一个百度首页的彩蛋——CSS3 Animation简介

    在百度搜索中有这样一个彩蛋:搜索“旋转”,“跳跃”,“反转”等词语,会出现相应的动画效果(搜索“反转”后的效果).查看源码可以发现,这些效果正是通过CSS3的animation属性实现的. 实现这个彩 ...

  6. 【Win 10应用开发】延迟共享

    延迟共享是啥呢,这么说吧,就是在应用程序打开共享面板选择共享目标时,不会设置要共享的数据,而是等到共享目标请求数据时,才会发送数据,而且,延迟操作可以在后台进行. 这样说似乎过于抽象,最好的诠释方法, ...

  7. ThreadPoolTimer -延迟执行, 周期执行

    介绍重新想象 Windows 8 Store Apps 之 线程池 通过 ThreadPoolTimer 实现延迟执行 通过 ThreadPoolTimer 实现周期执行 通过 ThreadPool ...

  8. Unity3D游戏开发初探—4.开发一个“疯狂击箱子”游戏

    一.预备知识—对象的”生“与”死“ (1)如何在游戏脚本程序中创建对象而不是一开始就创建好对象?->使用GameObject的静态方法:CreatePrimitive() 以上一篇的博文中的“指 ...

  9. iOS 分析一个支持GIF的UIImage扩展:SwiftGIF

    Github:https://github.com/bahlo/SwiftGif 这个extension代码不多,主要通过Apple的ImageIO框架进行解析GIF. 整个扩展最核心还是下面的函数, ...

随机推荐

  1. 多个div并排不换行

    1.所有div的父元素不换行   white-space: nowrap; 2.所有div设置为行内元素  display: inline-block; 基于java记账管理系统[尚学堂·百战程序员]

  2. MongoDB 创建数据库和查询数据

    1.选择数据库  use test  2.创建用户  db.createUser({user:"test01",pwd:"12345",roles:[{role ...

  3. JAVA笔记整理(六),JAVA中的多态

    JAVA引用变量有两个类型:一个是编译时类型,一个运行时类型 编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定.如果编译时类型和运行时类型不一样,就形成了多态. 因为子类其 ...

  4. vue 打印html

    1.https://github.com/xyl66/vuePlugs_printjs从这个路径下载print.js.放到你的代码中 2.我是放到我本地一个js文件中. 3.引入当前文件 //打印插件 ...

  5. Linux下常用mysql命令【2】

    1.开启和关闭 1.1.开启 systemctl start mysqld 1.2.关闭 systemctl stop mysqld 1.3.重启 systemctl restart mysqld 回 ...

  6. 团队第六次作业-Beta冲刺及发布说明

    1.相关信息 Q A 作业所属课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign/ 作业要求 https: ...

  7. Mybatis3.0-[tp_28-29]-映射文件-resultMap_自定义结果集映射规则_及关联环境的搭建

    笔记要点出错分析与总结工程组织 1.定义接口  EmployeeMapperPlus.java package com.dao; import com.bean.*; public interface ...

  8. Listener中@Autowired无法注入的问题

    最近在用监听器的时候遇到了spring无法注入的问题,代码如下,这个task总是null,包明明已经被扫到了,就是注入不进来. public class MyListener implements S ...

  9. 28-SQLServer带见证服务器的镜像搭建

    一.注意点 1.数据库的模式要是完整模式. 2.要对数据库完整备份和事务日志备份,分别还原到镜像库上,使用NORECOVERY模式. 3.镜像数据库是不允许删除和操作,即便查看属性也不行. 4.先删除 ...

  10. 使用tippecanoe把GeoJSON制作成供mapbox展示的矢量切片vectortile

    本文记录一下把geojson格式的数据制作成本地的矢量切片,并在mapbox中展示的过程. 1.切片 1.1 矢量数据需要先转换为geojson,如果是shp格式可以使用QGIS或者下载shp2gwo ...