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 相关文章推荐
刷新时清空文本框内容的js代码
Apr 23 Javascript
js 利用image对象实现图片的预加载提高访问速度
Mar 29 Javascript
js自动生成对象的属性示例代码
Oct 28 Javascript
javascript获取网页宽高方法汇总
Jul 19 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
Aug 09 Javascript
纯js实现手风琴效果代码
Apr 17 Javascript
jquery 抽奖小程序实现代码
Oct 12 Javascript
自己封装的一个简单的倒计时功能实例
Nov 23 Javascript
AngularJS2中一种button切换效果的实现方法(二)
Mar 27 Javascript
JS实现上传图片实时预览功能
May 22 Javascript
帝国cms首页列表页实现点赞功能
Oct 30 Javascript
JS实现吸顶特效
Jan 08 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 GeoIP的使用教程
2011/03/09 PHP
根据ip调用新浪api获取城市名并转成拼音
2014/03/07 PHP
PHP从尾到头打印链表实例讲解
2018/09/27 PHP
document.open() 与 document.write()的区别
2007/08/13 Javascript
非常不错的功能强大代码简单的管理菜单美化版
2008/07/09 Javascript
jQuery源码分析-03构造jQuery对象-源码结构和核心函数
2011/11/14 Javascript
input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
2013/04/02 Javascript
常用的JS验证和函数汇总
2014/12/23 Javascript
常用的jQuery前端技巧收集
2014/12/24 Javascript
javascript比较两个日期的先后示例代码
2014/12/31 Javascript
nodejs事件的监听与触发的理解分析
2015/02/12 NodeJs
jQuery AJAX timeout 超时问题详解
2016/06/21 Javascript
js实现复选框的全选和取消全选效果
2017/01/03 Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
2017/01/14 Javascript
jQuery实现页码跳转式动态数据分页
2017/12/31 jQuery
Vue源码探究之虚拟节点的实现
2019/04/17 Javascript
vue组件创建的三种方式小结
2020/02/03 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
vue实现树状表格效果
2020/12/29 Vue.js
[46:02]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第二局
2016/02/28 DOTA
windows系统下Python环境的搭建(Aptana Studio)
2017/03/06 Python
基于Django框架利用Ajax实现点赞功能实例代码
2018/08/19 Python
widows下安装pycurl并利用pycurl请求https地址的方法
2018/10/15 Python
python 动态生成变量名以及动态获取变量的变量名方法
2019/01/20 Python
Python 类,property属性(简化属性的操作),@property,property()用法示例
2019/10/12 Python
简述python Scrapy框架
2020/08/17 Python
python 6行代码制作月历生成器
2020/09/18 Python
HTML5 预加载让页面得以快速呈现
2013/08/13 HTML / CSS
2014年五四青年节活动策划书
2014/04/22 职场文书
小学生常见病防治方案
2014/06/06 职场文书
新教师培训方案
2014/06/08 职场文书
2014银行授权委托书样本
2014/10/04 职场文书
汽车车尾标语大全
2015/08/11 职场文书
热爱劳动主题班会
2015/08/14 职场文书
小学数学教师研修感悟
2015/11/18 职场文书
妇产科护理心得体会
2016/01/22 职场文书