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

因为在JavaScript中,mousedown、mouseup、click执行顺序是从左到右的,更重要的是一旦mousedown事件激活,正常情况下后面两个事件也肯定会被激活。平时我们在一个标签上只绑定一个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

在前端开发中,这些事件通常用于处理与鼠标交互相关的操作,以下是它们的含义: ### onClick `onClick` 事件在用户使用鼠标左键单击某个元素时触发。常用于处理按钮点击、链接点击等操作。例如,当用户点击一个提交按钮时,可以使用 `onClick` 事件来触发表单提交的逻辑。 ```html <!DOCTYPE html> <html lang="en"> <body> <button onclick="alert('Button clicked!')">Click me</button> </body> </html> ``` ### onContextMenu `onContextMenu` 事件在用户右键单击某个元素时触发。一般用于自定义右键菜单。当用户在网页上右键单击时,默认会弹出浏览器的上下文菜单,通过 `onContextMenu` 事件可以阻止默认行为并显示自定义的菜单。 ```html <!DOCTYPE html> <html lang="en"> <body> <div oncontextmenu="event.preventDefault(); alert('Custom context menu!')">Right click me</div> </body> </html> ``` ### onDoubleClick `onDoubleClick` 事件在用户快速连续两次点击鼠标左键时触发。可用于实现一些需要双击操作的功能,如双击打开文件、放大图片等。 ```html <!DOCTYPE html> <html lang="en"> <body> <div ondblclick="alert('Double clicked!')">Double click me</div> </body> </html> ``` ### onMouseDown `onMouseDown` 事件在鼠标按钮(左键、右键或中键)被按下时触发,不管鼠标是否在元素内部。它是鼠标交互的起始事件,常用于处理鼠标按下时的一些初始操作,如开始拖动元素。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmousedown="alert('Mouse button down!')">Press mouse here</div> </body> </html> ``` ### onMouseUp `onMouseUp` 事件在鼠标按钮(左键、右键或中键)被释放时触发,不管鼠标是否在元素内部。通常与 `onMouseDown` 事件配合使用,用于完成一些操作,如结束拖动元素。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmouseup="alert('Mouse button up!')">Release mouse here</div> </body> </html> ``` ### onMouseOver `onMouseOver` 事件在鼠标指针移动到某个元素上时触发,包括该元素的子元素。当鼠标进入元素的边界时,就会触发该事件,常用于实现鼠标悬停效果,如显示提示信息、改变元素样式等。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmouseover="this.style.backgroundColor = 'yellow'">Hover over me</div> </body> </html> ``` ### onMouseOut `onMouseOut` 事件在鼠标指针移出某个元素时触发,包括移出到该元素的子元素之外。与 `onMouseOver` 事件相对应,常用于取消鼠标悬停效果。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmouseover="this.style.backgroundColor = 'yellow'" onmouseout="this.style.backgroundColor = 'white'">Hover over and out</div> </body> </html> ``` ### onMouseMove `onMouseMove` 事件在鼠标指针在某个元素内部移动时持续触发。可以用于实现一些需要实时跟踪鼠标位置的功能,如绘制图形、拖动元素时实时更新位置等。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmousemove="showCoordinates(event)">Move mouse here</div> <p id="coords"></p> <script> function showCoordinates(event) { document.getElementById('coords').innerHTML = `X: ${event.clientX}, Y: ${event.clientY}`; } </script> </body> </html> ``` ### onMouseEnter `onMouseEnter` 事件在鼠标指针进入某个元素时触发,但不包括进入该元素的子元素时触发。与 `onMouseOver` 不同,`onMouseEnter` 不会在进入子元素时重复触发,常用于实现一些简单的鼠标进入效果。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmouseenter="this.style.backgroundColor = 'lightgreen'">Enter here</div> </body> </html> ``` ### onMouseLeave `onMouseLeave` 事件在鼠标指针离开某个元素时触发,但不包括离开到该元素的子元素时触发。与 `onMouseOut` 不同,`onMouseLeave` 不会在离开到子元素时触发,常用于取消鼠标进入效果。 ```html <!DOCTYPE html> <html lang="en"> <body> <div onmouseenter="this.style.backgroundColor = 'lightgreen'" onmouseleave="this.style.backgroundColor = 'white'">Enter and leave</div> </body> </html> ``` ### onDrag `onDrag` 事件在用户开始拖动某个元素时触发。通常与 `dragstart`、`dragend` 等事件配合使用,用于实现元素的拖动功能。 ```html <!DOCTYPE html> <html lang="en"> <body> <img src="example.jpg" draggable="true" ondrag="alert('Dragging...')"> </body> </html> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值