javascript当onmousedown、onmouseup、onclick同时应用于同一个标签节点Element


Posted in Javascript onJanuary 05, 2010

因为在JavaScript中,mousedown、mouseup、click执行顺序是从左到右的,更重要的是一旦mousedown事件激活,正常情况(不在mousedown事件中绑定的方法使用alert类似方法,因为弹出对象框就阻止了事件传递,即后续调用事件丢失)下后面两个事件也肯定会被激活。平时我们在一个标签上只绑定一个click事件,其实触发click事件也都调用了mousedown、mouseup等事件,只是它们调用周期极短,而且我们又没有编写相关函数与这两个事件绑定,所以不会觉察到。现在假设你要在一个标签上同时注册这几个事件,并具绑定指定的处理函数,在实际开发中,你将会遇到我下面提及的问题。
先通过一个简单例子测试并发现我说的问题,让你有个直观的印象,再接着看我的解决办法。

<div id="div1" onmousedown="mouseDownFun();" onmouseup="mouseUpFun();" onclick="clickFun();" style="background:#CCC; border:3px solid #999; width:200px; height:200px; padding:10px"></div> 
<input style="margin-top:10px" type="button" onclick="document.getElementById('div1').innerHTML='';" value="清除信息" /> 
<script type="text/javascript"> 
function mouseDownFun() 
{ 
document.getElementById('div1').innerHTML += 'mouseDown<br/>'; 
} 
function mouseUpFun() 
{ 
document.getElementById('div1').innerHTML += 'mouseUp<br/>'; 
} 
function clickFun() 
{ 
document.getElementById('div1').innerHTML += 'click<br/>'; 
} 
</script>

现在假设有这样一个需求:在一张图片上按下mousedown开始拖动这张图片,而在这张图片上发生mouseup鼠标释放就显示这张图片的相关信息。正常情况下要想mouseup绑定的函数执行,那么mousedown绑定的函数也执行了,而且还是先执行的,也就是说在你查看图片信息的时候,图片也在拖动中。其实你正真希望的可能是每次执行其中一个方法就好了,比如当你按下鼠标并很快就释放掉时,其实你是想看图片信息,而不是想拖动图片;相反,如果你按下鼠标并停顿了一下,表明你是想准备拖动图片,这时候查看信息方法不要执行。这怎么做到的呢,根据上面的分析,我发现可以用setTimeout函数来加以处理实现这样的需求(当然,如果你有发现更好的解决办法,一定要记得与我分享,哈)。下面给出完整例子,很简单,也加了注释,不另外解释了:
<div id="div1" onmousedown="mouseDownFun();" onmouseup="mouseUpFun();" style="background:#CCC; border:3px solid #999; width:200px; height:200px; padding:10px"></div> 
<input style="margin-top:10px" type="button" onclick="document.getElementById('div1').innerHTML='';" value="清除信息" /> 
<script type="text/javascript"> 
var doMouseDownTimmer = null; 
var isMouseDownDoing = false; 
function mouseDownFun() 
{ 
//因为mouseDownFun每次都会调用的,在这里重新初始化这个变量 
isMouseDownDoing = false; 
//延迟200毫秒才调用onmousedown真正的处理代码,如果在200毫秒内就释放鼠标,把 doMouseDownTimmer清除,那么onmousedown即使调用了,其实是没有调用到doMouseDown函数作为 onmousedown真正要处理的代码 
doMouseDownTimmer = setTimeout(doMouseDown,200); 
} 
function doMouseDown() 
{ 
//如果200毫秒后调用了这个方法,把isMouseDownDoing设置成true,表明发生了mouseDown实际处理,此后mouseUp就不要处理了 
isMouseDownDoing = true; 
document.getElementById('div1').innerHTML += 'mouseDown<br/>'; 
} 
function mouseUpFun() 
{ 
if (!isMouseDownDoing) 
{ 
clearTimeout(doMouseDownTimmer); //能进到这里来,不管三七二十一先把doMouseDownTimmer清除,不然200毫秒后doMouseDown方法还是会被调用的 
document.getElementById('div1').innerHTML += 'mouseUp<br/>'; 
} 
} 
</script>

相关话题:因为平时经常用的click事件都跑在mousedown、mouseup之后,我们可以用mouseup代替click(上面的例子就是这样用的),此时Element上就不要再注册click事件。当然,可以的话,还可以直接拿mousedown代替click,事件响应将更快,其中在Google的一些产品中有看到这样的写法,比如Gmail。
Javascript 相关文章推荐
锋利的jQuery 第三章章节总结的例子
Mar 23 Javascript
JS中获取函数调用链所有参数的方法
May 07 Javascript
AngularJS 自定义过滤器详解及实例代码
Sep 14 Javascript
基于Marquee.js插件实现的跑马灯效果示例
Jan 25 Javascript
vue cli构建的项目中请求代理与项目打包问题
Feb 26 Javascript
Vue中this.$router.push参数获取方法
Feb 27 Javascript
浅析Vue中method与computed的区别
Mar 06 Javascript
layui实现文件或图片上传记录
Aug 28 Javascript
Vue作用域插槽slot-scope实例代码
Sep 05 Javascript
vue-router的使用方法及含参数的配置方法
Nov 13 Javascript
vue-router 前端路由之路由传值的方式详解
Apr 30 Javascript
jQuery 数据缓存data(name, value)详解及实现
Jan 04 #Javascript
用AJAX返回HTML片段中的JavaScript脚本
Jan 04 #Javascript
Javascript解决常见浏览器兼容问题的12种方法
Jan 04 #Javascript
javascript 模拟点击广告
Jan 02 #Javascript
javascript 多种搜索引擎集成的页面实现代码
Jan 02 #Javascript
让firefox支持IE的一些方法的javascript扩展函数代码
Jan 02 #Javascript
javascript getElementsByClassName 和js取地址栏参数
Jan 02 #Javascript
You might like
php中$_SERVER[PHP_SELF] 和 $_SERVER[SCRIPT_NAME]之间的区别
2009/09/05 PHP
php的sprintf函数的用法 控制浮点数格式
2014/02/14 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
Ext JS Grid在IE6 下宽度的问题解决方法
2009/02/15 Javascript
Asp.net下利用Jquery Ajax实现用户注册检测(验证用户名是否存)
2010/09/12 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
JS定时刷新页面及跳转页面的方法
2013/07/04 Javascript
window.returnValue使用方法示例介绍
2014/07/03 Javascript
js中scrollTop()方法和scroll()方法用法示例
2016/10/03 Javascript
使用原生js封装的ajax实例(兼容jsonp)
2017/10/12 Javascript
vue checkbox 全选 数据的绑定及获取和计算方法
2018/02/09 Javascript
Vue 重置组件到初始状态的方法示例
2018/10/10 Javascript
Node.js之readline模块的使用详解
2019/03/25 Javascript
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
使用vue引入maptalks地图及聚合效果的实现
2020/08/10 Javascript
[01:10:58]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第二场 6.2
2018/06/03 DOTA
Python设计模式编程中Adapter适配器模式的使用实例
2016/03/02 Python
OpenCV 边缘检测
2019/07/10 Python
python程序 创建多线程过程详解
2019/09/23 Python
Win下PyInstaller 安装和使用教程
2019/12/25 Python
keras tensorflow 实现在python下多进程运行
2020/02/06 Python
Keras SGD 随机梯度下降优化器参数设置方式
2020/06/19 Python
tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this T
2020/06/22 Python
python3中calendar返回某一时间点实例讲解
2020/11/18 Python
详解Pycharm第三方库的安装及使用方法
2020/12/29 Python
家居饰品店创业计划书
2014/01/31 职场文书
社区爱国卫生月活动总结
2014/06/30 职场文书
励志演讲稿300字
2014/08/21 职场文书
党支部创先争优承诺书
2014/08/30 职场文书
2015年度团总支工作总结
2015/04/23 职场文书
2015年平安创建工作总结
2015/04/29 职场文书
电力工程合作意向书
2015/05/11 职场文书
幼儿园庆元旦主持词
2015/07/06 职场文书
解决hive中导入text文件遇到的坑
2021/04/07 Python
Apache Hudi数据布局黑科技降低一半查询时间
2022/03/31 Servers
PyTorch device与cuda.device用法
2022/04/03 Python