JS写不一样的悬停几秒后执行函数

2019-11-01 admin

大家好,我是 vortesnail。

前言:

最近这几个星期,一直都在维护自己的基于 React 的开源播放器组件,以为功能基本都差不多了,却忽视了播放器一个很重要的功能:鼠标悬停在视频播放界面时,在一定时间后鼠标会消失,视频下方的控制栏也会隐藏,呈现视频的最大可视化。但是鼠标稍微一动,一切恢复如初。用一张简单的 gif 图来说明的话,是下面这样子的: 屏幕录制-2019-10-31-11.18.41 (1).gif 有点犯难,它不是简单地移到元素(如视频)上,2秒后让它执行鼠标消失和控制栏消失的操作,因为一旦鼠标一动一点,都要恢复原样,不过好在结合 防抖 的思想以及自己的一些思考,实现了这个功能,并将其封装为一个工具函数,可供大家使用,当然,其中也有不足,也请各位能给予意见,我会结合给的意见更新这篇博客。

开始:

如果你现在需要使用这个功能,你希望用起来尽量简单,并且能达到你的使用要求,思来想去,给你暴露 4 个参数最为妥当:

  • element:你所希望操作的元素(比如上面 gif 中 “我是视频”这个 div 元素)
  • secondsLaterDoFn:你设定的时间之后,想做什么操作(比如上面 gif 中“鼠标消失,控制栏消失”)
  • seconds:你希望的时间,单位:ms(比如上面 gif 中我设定的时间为 2000ms)
  • reNormalFn:回归原样的操作(比如上面 gif 中控制栏和鼠标都回来)

那么,我们现在写一个函数,把这四个参数传进去,并对传入的 element 写两个监听事件,以及我们的清除定时器函数:

function HoverSD(element, secondsLaterDoFn, seconds, reNormalFn) {
  var timeout;
  var ele = element, secondsLDF = secondsLaterDoFn, secs = seconds, reNFn = reNormalFn;

  var clearTimer = function() {
    timeout && clearTimeout(timeout);
  }

  this.secondsHoverEX = function() {
    ele.addEventListener('mousemove', rebuildTimer);
    ele.addEventListener('mouseleave', clearTimer);
  }
}

window.HoverSD = HoverSD;

你也发现了, rebuildTimer 和 clearTimer 是个啥玩意儿?别急。 我们整理一下思路:在鼠标移到这个元素上面之后,我们要有一个定时器,在设定的时间过后,执行操作,但是,我们在设定的时间之内,又移动了鼠标,这时候需要把之前设定的定时器清除,重新开一个定时器,重新计时,这里的思想和 防抖 一模一样,于是我们初步的 rebuildTimer 如下:

var rebuildTimer = function() {
  var context = this;
  var args = arguments;
  clearTimer();
  timeout = setTimeout(() => {
    secondsLDF.apply(context, args);
  }, secs);
}

意思就是,当我们 mousemove 的时候,就会执行 rebuildTimer 函数,在这个函数内部,清除定时器,即每次移动之后,重新计时,执行 secondsLDF 。

可是我们传入的参数 reNormalFn (即 reNFn )并没有用到啊,它是用来恢复原状态的操作,我们直接插入在清除定时器之前就可以了。

var rebuildTimer = function() {
  var context = this;
  var args = arguments;

  reNFn.apply(context, args);

  clearTimer();
  timeout = setTimeout(() => {
    secondsLDF.apply(context, args);
  }, secs);
}

那我们在特定的时候想要移出这个元素的监听事件怎么办呢?比如在 React 中我们在 componentDidMount 中用了,需要在 componentWillUnmount 中去除监听事件,防止内存占用,那我们就需要再写一个移除事件的函数:

this.removeElemEventListener = function() {
  ele.removeEventListener('mousemove', rebuildTimer);
  ele.removeEventListener('mouseleave', clearTimer);
}

注意, removeEventListener 的参数,必须与监听时候的执行函数完全相同,且 不能有参数,不能有参数,不能有参数!!! ,我一开始就是写的有参数形式,怎么搞都搞不对。。。

现在把它封装成一个工具函数,放到 npm 上,直接安装使用,为了兼顾在不配置 webpack 情况下以及低版本浏览器情况下,我们可以这样来做:

// all code
function HoverSD(element, secondsLaterDoFn, seconds, reNormalFn) {
  var timeout;
  var ele = element, secondsLDF = secondsLaterDoFn, secs = seconds, reNFn = reNormalFn;

  var rebuildTimer = function() {
    var context = this;
    var args = arguments;
    reNFn.apply(context, args);
    clearTimer();
    timeout = setTimeout(() => {
      secondsLDF.apply(context, args);
    }, secs);
  }

  var clearTimer = function() {
    timeout && clearTimeout(timeout);
  }

  this.secondsHoverEX = function() {
    ele.addEventListener('mousemove', rebuildTimer);
    ele.addEventListener('mouseleave', clearTimer);
  }

  this.removeElemEventListener = function() {
    ele.removeEventListener('mousemove', rebuildTimer);
    ele.removeEventListener('mouseleave', clearTimer);
  }
}

window.HoverSD = HoverSD;

将主要的核心函数 secondsHoverEX 和 removeElemEventListener 通过 this. 暴露出来,再将这个函数暴露到 window 全局,安装之后可以直接通过

let hoversd = new window.HoverSD(elem, fn1, 2000, fn2);
hoversd.secondsHoverEX();
// ...
// other code here
// ...
hoversd.removeElemEventListener();

即可完成使用。

本篇文章收录于我的 个人blog,后续会致力于推出越来越多文章以及开源工具,如有帮助,赏个 star,谢谢各位老爷了!

后记:

非常感谢大家能看到最后,如果有朋友想要提出意见,欢迎来 github/issue 给我提建议,也可在下方评论直接提出,我个人觉得这个工具函数适用的场景还是蛮多的,如果能帮助到你,欢迎来此项目下赏个 star 。我会在项目主页关于此工具的使用做更详细的介绍,欢迎访问: github项目地址:https://github.com/vortesnail/hover-seconds-do

当然,厚着脸皮也希望大家能支持下我的基于 React 的开源播放器组件:https://github.com/vortesnail/qier-player 68747470733a2f2f69302e6864736c622e636f6d2f6266732f616c62756d2f646334363438326563343235656266373866383530316662343466303566386230316362646134622e706e67.png 下次再见,拜拜啦~

[转载]原文链接:https://segmentfault.com/a/1190000020874605

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-78743.html

文章标题:JS写不一样的悬停几秒后执行函数

相关文章
一些前端学习中好的书籍,整理
一、Javascript方面的书籍: 1 JavaScript权威指南(第6版):号称javascript圣经,前端必备;前端程序员学习核心JavaScript语言和由Web浏览器定义的JavaScript API的指南和综合参考手册; 2...
2015-11-12
为什么要选择Nodejs?Nodejs有什么好处?
什么?JavaScript还能用作服务器编程! Caleb Madrigal是来自美国密尔沃基市的一名软件顾问。四年前,他在听说“将JavaScript用作服务器端语言”这样的说法时,认为那是一个荒唐的想法。有那么多服务器端语言可供选择,为...
2015-11-12
js性能优化 如何更快速加载你的JavaScript页面
确保代码尽量简洁 不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具,只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。 ...
2015-11-12
10个强大的纯CSS3动画案例分享
我们的网页外观主要由CSS控制,编写CSS代码可以任意改变我们的网页布局以及网页内容的样式。CSS3的出现,更是可以让网页增添了不少动画元素,让我们的网页变得更加生动有趣,并且更易于交互。本文分享了10个非常炫酷的CSS3动画案例,希望大家...
2015-11-16
v-charts | 饿了么团队开源的基于 Vue 和 ECharts 的图表工具
在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts的出现正是为了解决这个 痛点。基于Vue2.0和echarts封装的v-charts图表组件,只需要统一提供一种对前后端都友好的数据格式 设置简...
2018-05-24
Node.js 2014这一年发生了什么
Node.js 的 2014 年充满了不幸和争议. 这一年 Noder 们经历了太多的伤心事, 经历了漫长的等待, 经历了沉重的分裂之痛. 也许 Noder 们不想回忆14年 Node.js land 发生的事情, 但正因为痛才更有铭记的价...
2015-11-12
Vue.js组件tab实现选项卡切换
本文实例为大家分享了vue插件tab选项卡的具体代码,供大家参考,具体内容如下 效果图: 代码如下: <!DOCTYPE html> <html lang="en"> <head> ...
2017-03-13
jsdom 中文文档(纯翻译)
jsdom是一个纯粹由 javascript 实现的一系列 web标准,特别是 WHATWG 组织制定的DOM和 HTML 标准,用于在 nodejs 中使用。大体上来说,该项目的目标是模拟足够的Web浏览器子集,以便用于测试和挖掘真实世界...
2018-05-14
React.js编程思想
JavaScript框架层出不穷,在很多程序员看来,React.js是创建大型、快速的Web应用的最好方式。这一款由Facebook出品的JS框架,无论是在Facebook还是在Instagram中,它的表现都非常出色。 使用React.j...
2015-11-12
从2014年的发展来展望JS的未来将会如何
<font face="寰�杞�闆呴粦, Arial, sans-serif ">2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
回到顶部