在mouseup事件处理程序中取消单击事件

编写一些拖放代码,我想在我的mouseup处理程序中取消单击事件。 我认为防止默认应该做的伎俩,但点击事件仍然被触发。

有没有办法做到这一点?


这不起作用:

test
$("#test").mouseup (function (e) { var a = 1; e.preventDefault(); }); $("#test").click (function (e) { var a = 2; });

我有同样的问题,也没有找到解决方案。 但我想出了一个似乎有用的黑客。

由于onMouseUp处理程序似乎无法取消对具有preventDefault或stopEvent或其他任何内容的链接的单击,我们需要使链接自行取消。 这可以通过编写onclick属性来完成,该属性在拖动开始时向a-tag返回false,并在拖动结束时将其删除。

由于onDragEnd或onMouseUp处理程序在浏览器解释单击之前运行,我们需要检查拖动结束的位置以及单击哪个链接等等。 如果它在拖动链接之外结束(我们拖动链接以便光标不再在链接上),我们删除onDragEnd中的onclick处理程序; 但如果它在光标在拖动链接上的位置结束(将启动一次点击),我们让onclick-handler自行删除。 够复杂吧?

不完整的代码,但只是为了向您展示这个想法:

 // event handler that runs when the drag is initiated function onDragStart (args) { // get the dragged element // do some checking if it's a link etc // store it in global var or smth // write the onclick handler to link element linkElement.writeAttribute('onclick', 'removeClickHandler(this); return false;'); } // run from the onclick handler in the a-tag when the onMouseUp occurs on the link function removeClickHandler (element) { // remove click handler from self element.writeAttribute('onclick', null); } // event handler that runs when the drag ends function onDragEnds (args) { // get the target element // check that it's not the a-tag which we're dragging, // since we want the onclick handler to take care of that case if (targetElement !== linkElement) { // remove the onclick handler linkElement.writeAttribute('onclick', null); } } 

我希望这能让你了解如何实现这一目标。 正如我所说,这不是一个完整的解决方案,只是解释了这个概念。

使用事件捕获阶段

在要取消click事件的元素周围放置一个元素,并为其添加捕获事件处理程序。

 var btnElm = document.querySelector('button'); btnElm.addEventListener('mouseup', function(e){ console.log('mouseup'); window.addEventListener( 'click', captureClick, true // <-- This registeres this listener for the capture // phase instead of the bubbling phase! ); }); btnElm.addEventListener('click', function(e){ console.log('click'); }); function captureClick(e) { e.stopPropagation(); // Stop the click from being propagated. console.log('click captured'); window.removeEventListener('click', captureClick, true); // cleanup } 
  

有一个解决方案!

这种方法对我很有用(至少在chrome中):

mousedown我向当前正在移动的元素添加一个类,并在mouseup删除该类。

该类所做的只是设置pointer-events:none

不知何故,这使它工作,并没有触发点击事件。

问题是有一个元素。 它需要响应点击。 它也需要被拖拽。 但是,当它被拖动时,它不需要在被删除时触发点击。

有点晚了,但也许它会帮助别人。 创建一个名为“noclick”的全局变量,并将其设置为false。 拖动项目时,将noclick设置为true。 在你的点击处理程序中,如果noclick为true,则将其设置为false,然后使用preventDefault,return false,stopPropagation等。但这不适用于Chrome,因为Chrome已经具有所需的行为。 只需将其设置为只有浏览器不是Chrome时,拖动function才会将noclick设置为true。

您的点击处理程序仍然会被触发,但至少它有一种方法可以知道它刚刚从拖动回来并且相应地表现。

对我的情况最好的解决方案是:

 el.addEventListener('mousedown', (event) => { clickTime = new Date() }) el.addEventListener('click', (event) => { if (new Date() - clickTime < 150) { // do something } }) 

这为用户提供了150ms的释放时间,如果超过150ms则被认为是暂停,而不是点击

因为它们是不同的事件,所以你不能取消onmouseup onclick ,如果你调用preventDefaultcancelBubble ,或者其他什么,你停止onmouseup事件被进一步处理。 onclick事件仍然悬而未决,但可以说是被解雇了。

你需要的是你自己的布尔标志,例如isDragging 。 拖动开始时(例如在onmousedown或其他内容中),您可以将此设置为true。

但是如果直接从onmouseup将其重置为false,则在收到onclick事件( isDragging == false )时不会再拖动,因为onmouseup会在onclick之前触发。

所以你需要做的是使用一个短暂的超时(例如setTimeout(function() {isDragging = false;}, 50); ),所以当你的onclick事件被触发时, isDragging仍然是true ,你的onclick事件处理程序可以只需要if(isDragging) return false; 在它做任何事之前。

这可能是可能的,但我不确定你是否可以使用jQuery处理这种evt管理。 这个代码示例不应该远离您的期望,或者至少给您一个方向。

 function AddEvent(id, evt_type, ma_fonction, phase) { var oElt = document.getElementById(id); // modèle W3C mode bubbling if( oElt.addEventListener ) { oElt.addEventListener(evt_type, ma_fonction, phase); // modèle MSIE } else if( oElt.attachEvent ) { oElt.attachEvent('on'+evt_type, ma_fonction); } return false; } function DelEvent(id, evt_type, ma_fonction, phase) { var oElt = document.getElementById(id); // modèle W3C mode bubbling if( oElt.removeEventListener ) { oElt.removeEventListener(evt_type, ma_fonction, phase); // modèle MSIE } else if( oElt.detachEvent ) { oElt.detachEvent('on'+evt_type, ma_fonction); } return false; } var mon_id = 'test'; var le_type_evt = "mouseup"; var flux_evt = false; // prevent bubbling var action_du_gestionnaire = function(e) { alert('evt mouseup on tag 
'); // 1ère méthode : DOM Lev 2 // W3C if ( e.target ) e.target.removeEventListener(le_type_evt, arguments.callee, flux_evt); // MSIE else if ( e.srcElement ) e.srcElement.detachEvent('on'+le_type_evt, arguments.callee); // 2ème méthode DOM Lev2 // DelEvent(mon_id, le_type_evt, action_du_gestionnaire, flux_evt); }; AddEvent(mon_id, le_type_evt, action_du_gestionnaire, flux_evt);

我最近遇到了同样的问题。 这是我的解决方案:)

  initDrag: function (element) { var moved = false, target = null; function move(e) { // your move code moved = true; }; function end(e) { var e = e || window.event, current_target = e.target || e.srcElement; document.onmousemove = null; document.onmouseup = null; // click happens only if mousedown and mouseup has same target if (moved && target === current_target) element.onclick = click; moved = false; }; function click(e) { var e = e || window.event; e.preventDefault(); e.stopPropagation(); // this event should work only once element.onclick = null; }; function init(e) { var e = e || window.event; target = e.target || e.srcElement; e.preventDefault(); document.onmousemove = move; document.onmouseup = end; }; element.onmousedown = init; }; 

这是我拖动并单击相同元素的解决方案。

 $('selector').on('mousedown',function(){ setTimeout(function(ele){ele.data('drag',true)},100,$(this)); }).on('mouseup',function(){ setTimeout(function(ele){ele.data('drag',false)},100,$(this)); }).on('click',function(){ if($(this).data('drag')){return;} // put your code here }); 

我使用的解决方案如下:

 var disable_click = false; function click_function(event){ if (!disable_click){ // your code } } function mouse_down_function(event){ disable_click = false; // will enable the click everytime you click // your code } function mouse_up_function(event){ // your code } function mouse_drag_function(event){ disable_click = true; // this will disable the click only when dragging after clicking // your code } 

根据名称将每个function附加到相应的事件!

我的解决方案不需要全局变量或超时或更改html元素只是jquery肯定在普通js中有一些兼容性。

我为onClick声明了一个函数

 function onMouseClick(event){ // do sth } 

我为MouseDown声明了一个函数(你也可以在鼠标中执行相同操作)来决定是否处理onclick事件

 function onMouseDown(event){ // some code to decide if I want a click to occur after mouseup or not if(myDecision){ $('#domElement').on("click", onMouseClick); } else $('#domElement').off("click"); } 

快速注意:你应该确保这一点
$('#domElement').on("click", onMouseClick); 不会多次执行。 在我看来,如果它是onMouseClick也将被多次调用。

 $(document).mouseup(function(event){ event.preventDefault(); // this prevents only a default action but previously assigned listeners will be called event.stopImmediatePropagation() // if there are others listeners which that shouldn't call } 
 $(document).mouseup(function(event){ // make sure to set the event parameter event.preventDefault(); // prevent default, like you said }); 

需要注意的重要事项是event参数。

编辑:你想取消阻力?

我知道这样做的方法是使用bind() (对于较旧的jQuery版本)或on() (对于jQuery 1.7+)来附加mousedown事件,然后分别使用unbind()off()来分离它。

 $(document) .on("mousedown", function(){...}) .on("mouseup", function(){ $(document).off("mousedown"); }); 

如果您希望禁止click事件,则只在click事件处理程序中添加语句event.preventDefault() ,而不是mouseup事件处理程序。 使用以下代码,您将获得它的工作。

 
test

希望这能解决你的问题。