急求解决方法 鼠标移动太快时 onmouseout事件无法触发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了急求解决方法 鼠标移动太快时 onmouseout事件无法触发相关的知识,希望对你有一定的参考价值。

js代码:
<script type="text/javascript">
function changeIcon(elementStr,id)

elementStr.style.display = "none";
document.getElementById(id).style.display = "";

</script>

html
<table id="map_statr" cellpadding="0" cellspacing="0" onmouseover="changeIcon(this,'map_end')" style="padding-left: 5px">
<tr>
<th style="width:7px"></th>
<td><img src="images/IcoAndBtn/ico_34.png" style="vertical-align:middle;">地图</td>
<td style="width:4px"></td>
</tr>
</table>
<table id="map_end" cellpadding="0" cellspacing="0" onmouseout="changeIcon(this,'map_statr')" style="display: none;padding-left: 5px">
<tr>
<th style="width:7px"><img src='images/IcoAndBtn/btn2_1.png'></th>
<td style="background-image: url(images/IcoAndBtn/btn2_2.png);width:atuo"><img src="images/IcoAndBtn/ico_34.png" style="vertical-align:middle;">地图</td>
<td style="width:4px"><img src='images/IcoAndBtn/btn2_3.png'></td>
</tr>
</table>

有时鼠标移动太快,onmouseout事件无法触发

话说有一个DIV元素,其内部有一个IMG元素和SPAN元素,不用理会这两个内部元素怎么布局,这不是我要讨论的重点。

为了实现一些特殊的效果,我需要利用TD的onmouseover和onmouseout事件,测试时就会发现如下的状况:

当鼠标移入DIV内部时,onmouseover事件被触发;接着再鼠标移动到DIV内部的IMG或者SPAN元素之上,我们肯定不会认为这时鼠标已经移到了DIV的外边,但奇怪的是onmouseout事件触发了,而且紧接着onmouseover事件也马上被触发了。

这可不是我想要的,那么怎么来“屏蔽”内部元素给外层元素带来的Javascript事件干扰呢?

这里列举两种方法:

一. setTimeout

因为在鼠标移动到内部元素之上而触发了外层元素的onmouseout事件后,外层元素的onmouseover也会马上触发,所以我们只需要把外层元素的onmouseout事件需要执行的动作延迟很短的一段时间来运行,然后在onmouseover事件中再执行clearTimeout方法,这样就可以避免内部元素引起的事件干扰。

具体的执行过程请看下图(纵向的虚线表示时间):

这是个很巧妙的的方法,因为当onmouseout触发后,实质性的方法并没有马上执行,而是要等待一小段时间。如果在这段时间里马上又触发了 onmouseover事件,那么基本上就可以肯定onmouseout事件的触发是因为内部元素的干扰了,所以在onmouseover事件中使用 clearTimeout来阻止延时的方法执行。

二.contains

在onmouseover时先进行如下判断,结果为true时再执行方法体:

1 $("#popFormDiv").mouseover(function () 2 var s = event.fromElement || event.relatedTarget;3 if (!this.contains(s)) $(this).show("slow"); 4 );

在onmouseout时先进行如下判断,结果为true时再执行方法体:

$("#popFormDiv").mouseout(function () var s = event.toElement || event.relatedTarget; if (!this.contains(s)) $(this).hide("slow"); );

下面来解释一下上面两行代码的含义:

在IE中,所有的HTML元素都有一个contains方法,它的作用是判断当前元素内部是否包含指定的元素。我们利用这个方法来判断外层元素的事件是不是因为内部元素而被触发,如果内部元素导致了不需要的事件被触发,那我们就忽略这个事件。

event.fromElement指向触发onmouseover和onmouseout事件时鼠标离开的元素;event.toElement指向触发onmouseover和onmouseout事件时鼠标进入的元素。

那么上面两行代码的含义就分别是:

○ 当触发onmouseover事件时,判断鼠标离开的元素是否是当前元素的内部元素,如果是,忽略此事件;

○ 当触发onmouseout事件时,判断鼠标进入的元素是否是当前元素的内部元素,如果是,忽略此事件;

这样,内部元素就不会干扰外层元素的onmouseover和onmouseout事件了。

但问题又来了,非IE的浏览器并不支持contains函数,不过既然我们已经知道了contains函数的作用,就可以自行添加如下的代码来为非IE浏览器增加contains支持:

1 if (typeof (HTMLElement) != "undefined") 2 3 HTMLElement.prototype.contains = function (obj) 4 5 while (obj != null && typeof (obj.tagName) != "undefined") 6 7 if (obj == this) 8 9 return true;10 11 obj = obj.parentNode;12 13 14 15 return false;16 17 ;18 19
参考技术A 楼主这个问题目前无法解决~~这个是你系统对于浏览器的反映的问题~~楼主应该知道鼠标的每个操作都会和系统进行交互~~但是这之间都会存在一个时间差只是时间差非常段楼主无法感觉,当你用很快的速度进行移出操作的时候,电脑并没有能够识别,也是这个原因了~~就好像有人用刀砍你能躲~~但是子弹你就躲不了~~反应的问题 参考技术B 单击开始--控制面板--鼠标--指针选项--选择指针移动速度 自己调整就行了

UIButton sender.titleLabel?.text?.toInt() 按下太快时给出未更新的值

【中文标题】UIButton sender.titleLabel?.text?.toInt() 按下太快时给出未更新的值【英文标题】:UIButton sender.titleLabel?.text?.toInt() gives not updated value when pressed too fast 【发布时间】:2015-02-06 14:19:00 【问题描述】:

在我的应用程序中,我按下按钮,它会通过 iOS 默认按钮动画更改背景颜色等数字。按钮的默认行为就像 number 只能在区间 [x, x+1] 或 [x-1, x] 中,其中 x 是初始值。但是,如果快速按下按钮,则类似的数字只会迅速增加或迅速减少。

func likeButtonAction(sender:UIButton!) 
    var oldValue = sender.titleLabel?.text?.toInt()
    println("oldvalue \(oldValue)")
        if sender.selected 
            //upvote
            sender.setTitle(String(oldValue! + 1), forState: UIControlState.Normal|UIControlState.Selected)
            println("inc \(oldValue! + 1)")

         else 
            //downvote
            sender.setTitle(String(oldValue! - 1), forState: UIControlState.Normal|UIControlState.Selected)
            println("dec \(oldValue! - 1)")
        

编辑1: 快速按下时输出为:

oldvalue Optional(3)
inc 4
oldvalue Optional(4)
dec 3
oldvalue Optional(3)
inc 4
oldvalue Optional(4)
dec 3
oldvalue Optional(4)
inc 5
oldvalue Optional(5)
dec 4
oldvalue Optional(5)
inc 6
oldvalue Optional(6)
dec 5
oldvalue Optional(6)
inc 7
oldvalue Optional(7)
dec 6
oldvalue Optional(7)
inc 8
oldvalue Optional(8)
dec 7
oldvalue Optional(8)
inc 9
oldvalue Optional(9)
dec 8
oldvalue Optional(8)
inc 9

编辑2: 解决方案: 这正常工作,但我不知道为什么。解释将不胜感激

func likeButtonAction(sender:UIButton!) 
        if sender.selected 
            //upvote
            sender.setTitle(String((sender.titleLabel?.text?.toInt())! + 1), forState: UIControlState.Normal|UIControlState.Selected)
         else 
            //downvote
            sender.setTitle(String((sender.titleLabel?.text?.toInt())! - 1), forState: UIControlState.Normal|UIControlState.Selected)
        

【问题讨论】:

【参考方案1】:

这将不起作用,因为

 if sender.backgroundImageForState(UIControlState.Normal) == UIImage(named: "like.png")

总是假的..

UIImage(named: "like.png")

将创建新的 UIImage 实例。

您可以将“标签”分配给任何视图(在本例中为 UIButton)以处理此类情况。

【讨论】:

以这种方式改变了它,但问题仍然存在。所以我的假设是错误的,我将编辑该问题【参考方案2】:

我的建议是将 .Normal 和 .Selected 的按钮状态分别设置为“like.png”和“liked.png”。那么你的代码可以很简单:

func likeButtonAction(sender:UIButton!) 
        if sender.selected 
            //upvote
            sender.setTitle(String(oldValue! + 1), forState: UIControlState.Normal)
            sender.setTitleColor(MyStyle.ThemeSecondColor, forState: UIControlState.Normal)
         else 
            //downvote
            sender.setTitle(String(oldValue! - 1), forState: UIControlState.Normal)
            sender.setTitleColor(MyStyle.ThemeColor, forState: UIControlState.Normal)
        
        //Quickly flip the button state to the opposite of what it was
        sender.selected = !sender.selected

编辑:

嗯,你可以实现一个变量来保存“计数”并首先设置它,然后用它设置按钮的值,而不是把值拉入和拉出按钮标题:

var likeCount:Int = [SET THIS FROM YOUR STORAGE] || 0
func likeButtonAction(sender:UIButton!) 
    if sender.selected 
        //upvote
        likeCount++
        println("inc \(likeCount!)")

     else 
        //downvote, but do not allow negative values
        if likeCount == 0
            likeCount = 0
         else 
            likeCount--
        
        println("dec \(likeCount!)")
    
    sender.setTitle(String(likeCount!), forState: UIControlState.Normal)
    sender.selected = !sender.selected

这将使值的跟踪保持独立,并防止 UI 潜在地阻碍该过程。

【讨论】:

谢谢,但没用。快速按下时,静止数字变化不准确。

以上是关于急求解决方法 鼠标移动太快时 onmouseout事件无法触发的主要内容,如果未能解决你的问题,请参考以下文章

当我的脸移动得太快时,OpenCV 人脸检测会中断

iOS:UITableView 在滚动太快时混淆数据

问个问题 在火狐下 div 设置了 onmouseout 为啥有时鼠标div上面移动时 也会触发onmouseout ie下就不会

如果鼠标移动太快,SwiftUI onHover 不会注册鼠标离开元素

如何在拖动鼠标时平滑填充椭圆

jQuery 问题 - mouseover/mouseout 太快