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 相关文章推荐
加随机数引入脚本不让浏览器读取缓存
Sep 04 Javascript
jQuery实现统计复选框选中数量
Nov 24 Javascript
js限制input标签中只能输入中文
Jun 26 Javascript
jQuery on()绑定动态元素出现的问题小结
Feb 19 Javascript
JS中多步骤多分步的StepJump组件实例详解
Apr 01 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(二)
Jan 21 Javascript
JS创建Tag标签的方法详解
Jun 09 Javascript
vue中路由参数传递可能会遇到的坑
Dec 07 Javascript
Express进阶之log4js实用入门指南
Feb 10 Javascript
JS实现的贪吃蛇游戏完整实例
Jan 18 Javascript
es6数据变更同步到视图层的方法
Mar 04 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
Aug 20 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 substr,mb_substr以及mb_strcut的区别和用法
2013/06/21 PHP
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
使用PHP生成二维码的方法汇总
2015/07/22 PHP
PHP 将dataurl转成图片image方法总结
2016/10/14 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
Sample script that deletes a SQL Server database
2007/06/16 Javascript
可以用来调试JavaScript错误的解决方案
2010/08/07 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
2014/10/29 Javascript
深入探讨javascript函数式编程
2015/10/11 Javascript
jQuery中事件与动画的总结分享
2016/05/24 Javascript
jQuery简单实现遍历单选框的方法
2017/03/06 Javascript
移动端效果之IndexList详解
2017/10/20 Javascript
js 两数组去除重复数值的实例
2017/12/06 Javascript
js+SVG实现动态时钟效果
2018/07/14 Javascript
在Vuex使用dispatch和commit来调用mutations的区别详解
2018/09/18 Javascript
Vue页面手动刷新,实现导航栏激活项还原到初始状态
2020/08/06 Javascript
深入了解Vue3模板编译原理
2020/11/19 Vue.js
JS removeAttribute()方法实现删除元素的某个属性
2021/01/11 Javascript
JS canvas实现画板和签字板功能
2021/02/23 Javascript
实例讲解Python中的私有属性
2014/08/21 Python
python使用matplotlib绘图时图例显示问题的解决
2017/04/27 Python
Python2和Python3中print的用法示例总结
2017/10/25 Python
Python tkinter事件高级用法实例
2018/01/31 Python
matplotlib subplots 设置总图的标题方法
2018/05/25 Python
Django中提示消息messages的设置方式
2019/11/15 Python
Pytorch之view及view_as使用详解
2019/12/31 Python
python pandas移动窗口函数rolling的用法
2020/02/29 Python
python数据分析工具之 matplotlib详解
2020/04/09 Python
python实现处理mysql结果输出方式
2020/04/09 Python
python 爬取B站原视频的实例代码
2020/09/09 Python
HTML5 语音搜索(淘宝店语音搜素)
2013/01/03 HTML / CSS
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
2013/01/09 HTML / CSS
网络工程师面试(三木通信技术有限公司)
2013/06/05 面试题
2015年发展党员工作总结报告
2015/03/31 职场文书
酒店客房服务员岗位职责
2015/04/09 职场文书
OpenCV-Python 实现两张图片自动拼接成全景图
2021/06/11 Python