ontouchstart ontouchmove eventos event div changedtouches javascript jquery javascript-events click mouseup

javascript - ontouchmove - Cancelar evento de clic en el controlador de eventos de mouseup



ontouchmove jquery (11)

$(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 }

Al escribir un código de arrastrar y soltar, me gustaría cancelar los eventos de clic en mi controlador de mouseup. Pensé que la prevención de los valores predeterminados debería ser el truco, pero el evento de clics todavía está activado.

¿Hay alguna forma de hacer esto?

Esto no funciona:

<div id="test">test</div> <script> $("#test").mouseup (function (e) { var a = 1; e.preventDefault(); }); $("#test").click (function (e) { var a = 2; });


$(document).mouseup(function(event){ // make sure to set the event parameter event.preventDefault(); // prevent default, like you said });

Lo importante a tener en cuenta es el parámetro de event .

EDITAR: ¿Desea cancelar el arrastre?

La forma en que sé hacer esto es usar bind() (para versiones antiguas de jQuery) o on() (para jQuery 1.7+) para adjuntar el evento mousedown, luego use unbind() o off() respectivamente para separarlo.

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


Si desea suprimir el evento click, debe agregar la sentencia event.preventDefault () únicamente en el controlador de eventos click y no en el controlador de eventos mouseup. Use el siguiente código para que funcione.

<div id="test">test</div> <script> $("#test").mouseup (function (e) { var a = 1; }); $("#test").click (function (e) { e.preventDefault(); var a = 2; });

Espero que esto resuelva tu problema.


Podría ser posible, pero no estoy seguro de si puedes manejar este tipo de administración evt con jQuery. Este ejemplo de código no debe estar lejos de sus expectativas o al menos darle una dirección.

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 <div>''); // 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);


Tuve el mismo problema y tampoco encontré una solución. Pero se me ocurrió un truco que parece funcionar.

Como el controlador onMouseUp no parece poder cancelar el clic en un enlace con preventDefault o stopEvent o algo así, tenemos que hacer que el enlace se cancele solo. Esto se puede hacer escribiendo un atributo onclick que devuelve falso en la etiqueta a cuando comienza la resistencia y eliminándolo cuando termina la operación de arrastrar.

Y dado que los manejadores onDragEnd o onMouseUp se ejecutan antes de que el navegador interprete el clic, debemos verificar dónde finaliza el arrastre y qué enlace se hace clic, y así sucesivamente. Si termina fuera del enlace arrastrado (arrastramos el enlace para que el cursor ya no esté en el enlace), eliminamos el controlador onclick en onDragEnd; pero si termina donde está el cursor sobre el enlace arrastrado (se iniciará un clic), dejamos que el manejador onclick se elimine solo. Complicado, ¿verdad?

NO ES EL CÓDIGO COMPLETO, pero solo para mostrarle la idea:

// 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); } }

Espero que esto te dé una idea de cómo se puede lograr esto. Como dije, esta no es una solución completa, solo explica el concepto.


El problema es que hay un elemento. Necesita responder a los clics. También necesita ser arrastrado. Sin embargo, cuando se arrastra, no debe activar el clic cuando se suelta.

Un poco tarde, pero tal vez ayude a alguien más. Cree una variable global llamada "noclick" o algo así y configúrelo como falso. Al arrastrar el elemento, establezca noclick en verdadero. En su controlador de clics, si noclick es verdadero, establézcalo en falso y luego evite Default, return false, stopPropagation, etc. Esto no funcionará en Chrome, ya que Chrome ya tiene el comportamiento deseado. Simplemente haga que la función de arrastre solo establezca noclick en verdadero si el navegador no es Chrome.

Su manejador de clics seguirá siendo disparado, pero al menos tiene una forma de saber que acaba de regresar del arrastre y comportarse en consecuencia.


Como se trata de eventos diferentes, no puede cancelar la función onclick desde onmouseup , si llama a preventDefault o cancelBubble , o lo que sea, está onmouseup evento onmouseup se onmouseup procesando. El evento onclick todavía está pendiente, pero debe ser despedido, por así decirlo.

Lo que necesita es su propia bandera booleana, por ejemplo, isDragging . Puede establecer esto en verdadero cuando se inicie el arrastre (por ejemplo, dentro de onmousedown , o lo que sea).

Pero si restablece esto a falso directamente desde onmouseup , ya no arrastrará más cuando reciba su evento onclick ( isDragging == false ), porque onmouseup antes de que haga onmouseup .

Entonces, lo que debe hacer es usar un tiempo de espera corto (por ejemplo, setTimeout(function() {isDragging = false;}, 50); ), de modo que cuando se isDragging su evento onclick , isDragging seguirá siendo true y su controlador de eventos onclick podrá simplemente tenga if(isDragging) return false; antes de hacer cualquier otra cosa


Recientemente me enfrenté con el mismo problema. Aquí está mi solución :)

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; };


¡Hay una solucion!

Este enfoque me funciona muy bien (al menos en Chrome):

en mousedown agrego una clase al elemento que se está moviendo actualmente y en el mouseup, elimino la clase.

Todo lo que hace la clase es establecer punteros-eventos: ninguno

De alguna manera, esto hace que funcione y el evento de clic no se activa.


Usa la fase de captura de eventos

Coloque un elemento alrededor del elemento para el que desea cancelar el evento click y agregue un controlador de eventos de captura.

<div id="capture"> <button id="test_capture">Test capture click event</button> </div> <script> $("#test_capture").mouseup(function (e) { alert(''mouseup''); var captureClick = function(e) { alert(''click captured''); e.stopPropagation(); // Stop the click from being propagated. this.removeEventListener(''click'', captureClick, true); // cleanup } $(''#capture'')[0].addEventListener( ''click'', captureClick, true // <-- This registeres this listener for the capture // phase instead of the bubbling phase! ); }); $("#test_capture").click(function (e) { alert(''click''); }); <script>

Demostración de JSFiddle

Lo que pasa:

Antes de que se active el evento click en el button el evento click en el div circundante se dispara porque se registró para la fase de captura en lugar de la fase de burbujeo.

El controlador captureClick detiene la propagación de su evento de click y evita que se llame al controlador de click en el botón. Exactamente lo que querías Luego se elimina para la limpieza.

Capturar vs. Burbujear:

La fase de captura se llama desde la raíz de DOM hasta las hojas, mientras que la fase de burbujeo proviene de la hoja de la raíz (ver: explicación maravillosa del orden de los eventos ).

jQuery siempre agrega eventos a la fase de burbujeo, por eso tenemos que usar JS puro aquí para agregar nuestro evento de captura específicamente a la fase de captura.

Tenga en cuenta que IE introdujo el modelo de captura de eventos del W3C con IE9, por lo que no funcionará con IE <9.

Con la API de eventos actual no puede agregar un nuevo controlador de eventos a un elemento DOM antes de otro que ya se agregó. No hay un parámetro de prioridad y no existe una solución segura entre navegadores para modificar la lista de oyentes de eventos .


Esta es mi solución para arrastrar y hacer clic en el mismo elemento.

$(''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 });