视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
jQuery关于鼠标事件mouseDown和doubleClick运行冲突的问题解决
2020-11-27 20:18:22 责编:小采
文档
首先,现在有一个需求是在一个对象上监听mouseDown和mouseDoubleClick事件,两种事件对应不同的解决方案,鼠标按下执行拖拽功能,鼠标双击是释放技能功能。但是问题来了,不管Click几次,肯定是down先触发,不管如何都是down触发。

然后呢,我问了一高手,他说,可以推迟按下的处理函数,推迟200ms(因为大概在200ms内算双击),在这200ms内,有双击了,就先执行双击事件,并且要把原本双击事件的处理函数跟按下的处理函数一起写在mouseDown里。我这样做了,还是出错。因为,即使推迟了执行按下的函数,可最终还是要执行按下的函数(就是先执行原来双击事件,在执行推迟200ms的按下函数)。

所以,问题就是:我怎么让down函数知道我到底执行的是拖拽还是释放呢?
我觉得这像死锁功能,一个功能执行完了,那在这个对象上的那个功能就不能执行了。啊啊啊,想的头都大了,还是想不出来!

大家虽然热心提供了方法,我也一一试了,但是还是解决不了我的需求,可能因为我没有把需求彻底说清楚吧,现在提供一张我自己总结的,这个问题可能的流程图:

其实也不一定是两两排斥的,因为毕竟市面上那么多页游的背包都是这样做的了···
给个思路:在UP事件的处理函数中做下判断,如果鼠标还在背包,就弹出二级菜单,如果鼠标已经不在背包,就是拖拽操作。

doubleClickEnabled = true;要双击的对象只有设置为true,才能侦听到鼠标双击事件,也才能将单击和双击事件区分出来,如果两次单击相隔时间很小,会被视为双击
看看这个有没有漏掉

拖拽除了单击之外还有一个特征,即单击后鼠标出现移动。
满足如下条件即判断为“释放”:
有正在拖拽的物体,单击一次鼠标,在300ms内再单击一次鼠标,第二次单击时的位置与第一次单击时的位置相差不到5像素(手滑误差)

其它的行为,
根据是否已经有拖拽物来判定为
“拖拽”
或者
“无效操作”

你那位高手说的对啊,当得到mouseDown后给一个延时,
200ms内得到第二个mouseDown事件则是释放了,就取消延时后的拖拽事件
200ms后没收到第二个mouseDown且也没收到mouseUp事件那就拖拽呗;

而且不一定非要这么做啊
可以把对象细分下嘛,对象边框只响应拖拽事件,
对象中间只响应释放事件

或者把对象拖到界面外释放对象,什么的。。
如果客户执着就没办法了

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;

/**
* ...
* @author 小松626
*/
public class Main extends Sprite
{
private var _mc:Sprite;
private var date2Time:Number;
private var date1:Date;
private var date1Time:Number;
private var date2:Date;

public function Main():void
{
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
creatMc();
_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragMouseDownHandler);
}

private function creatMc():void 
{
_mc = new Sprite();
_mc.graphics.beginFill(0xff0000);
_mc.graphics.drawCircle(0, 0, 20);
_mc.graphics.endFill();
addChild(_mc);
_mc.x = 50;
_mc.y = 50;
}

private function dragMouseDownHandler(e:MouseEvent):void
{
_mc.startDrag(false); 
date1 = new Date();
date1Time = date1.time;
stage.addEventListener(MouseEvent.MOUSE_UP, dragMouseUpHandler); //鼠标抬起侦听事件
}

/*
* 鼠标抬起侦听事件函数
*/
private function dragMouseUpHandler(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, dragMouseUpHandler); //鼠标抬起侦听事件(移除) 
date2 = new Date();
date2Time = date2.time;
if (date2Time - date1Time > 100)
{
_mc.stopDrag(); //停止拖拽
}
else
{
_mc.doubleClickEnabled = true;
_mc.addEventListener(MouseEvent.DOUBLE_CLICK, mcDoubleClickHandler);
}
}

private function mcDoubleClickHandler(e:MouseEvent):void 
{
trace("双击mc");
}

}

}

加一个true或false的判断,表示是否刚发生过双击。如果刚发生过双击(双击事件发生时,设其为true),200ms后就不执行原先的单机函数,只把那个变量重新设为flase。

下载本文
显示全文
专题