pagina obtiene objeto funcion forma eventos elementos ejemplos ejecutar dinĂ¡micamente dinĂ¡mica despues creados creado como cargar carga bootstrap asociar asincrona antes acceso javascript jquery events event-bubbling propagation

obtiene - Javascript con jQuery: haga clic y haga doble clic en el mismo elemento, efecto diferente, uno desactiva el otro



on double click jquery (9)

Al agregar respuesta de @puttyshell, este código tiene espacio para una función visualSingleClick . Esta ejecución antes de setTimeout y está destinada a mostrar al usuario alguna acción visual para la acción antes del tiempo de espera, y con eso puedo usar un mayor tiempo de espera. Estoy usando esto en una interfaz de navegación de Google Drive para mostrar al usuario que el archivo o la carpeta en la que hizo clic está seleccionado. Google Drive en sí mismo hace algo similar, pero no lo vio código.

/* plugin to enable single and double click on same object */ $.singleDoubleClick = function(visualSingleClk, singleClk, doubleClk) { return (function() { var alreadyclicked = false; var alreadyclickedTimeout; return function(e) { if (alreadyclicked) { // double alreadyclicked = false; alreadyclickedTimeout && clearTimeout(alreadyclickedTimeout); doubleClk && doubleClk(e); } else { // single alreadyclicked = true; visualSingleClk && visualSingleClk(e); alreadyclickedTimeout = setTimeout(function() { alreadyclicked = false; singleClk && singleClk(e); }, 500); } } })(); }

Tengo una situación interesante: tengo una fila en la tabla que, actualmente, muestra que es una contraparte oculta cuando hago clic en el botón "Expandir". La fila original (no oculta) que contiene el botón expandir también tiene algo de contenido en una celda determinada que, al hacer clic, se puede editar. Me gustaría eliminar el botón expandir y permitir la expansión de la fila mediante doble clic en cualquier lugar de la fila, incluido el campo que se puede editar cuando se hace clic en él. Ya puedes oler el problema aquí.

Cuando hago doble clic en una fila, primero se activan dos eventos de clic antes de que se produzca el doble clic. Esto significa que si hago doble clic en el campo, se convertirá en uno editable y la fila se expandirá. Me gustaría prevenir esto. Deseo que el doble clic impida que se active un solo clic y que el clic solo se realice como de costumbre.

Usar event.stopPropagation () claramente no funcionará ya que son dos eventos diferentes.

¿Algunas ideas?

Editar (algún semi-pseudo código):

Versión original:

<table> <tbody> <tr> <td><a href="javascript:$(''#row_to_expand'').toggle();" title="Expand the hidden row">Expand Row</a></td> <td>Some kind of random data</td> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[0]->value("First editable value") ?></td> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[1]->value("Second editable value") ?></td> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[2]->value("Third editable value") ?></td> <!-- ... --> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[n]->value("Nth editable value") ?></td> </tr> <tr style="display: none" id="row_to_expand"> <td colspan="n">Some hidden data</td> </tr> </tbody> </table>

Versión deseada:

<table> <tbody> <tr ondblclick="$(''#row_to_expand'').toggle()"> <td>Some kind of random data</td> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[0]->value("First editable value") ?></td> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[1]->value("Second editable value") ?></td> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[2]->value("Third editable value") ?></td> <!-- ... --> <td><?= $editable_cell_which_turns_into_an_input_field_on_single_click[n]->value("Nth editable value") ?></td> </tr> <tr style="display: none" id="row_to_expand"> <td colspan="n">Some hidden data</td> </tr> </tbody> </table>

Aclamaciones


El problema solo ocurre cuando se hace clic en el campo editable, por lo tanto, adjunte un controlador de click regular a ese elemento que cancelará la propagación del evento ( vea stopPropagation ) y establecerá un tiempo de espera ( setTimeout(...) ) para, digamos, 600 ms ( el tiempo predeterminado entre dos clics para que se considere un doble clic es de 500ms [src] ). Si, en ese momento, no se ha producido la dblclick (puede tener una var accesible en ambos controladores de eventos que actúe como una bandera para detectar esto), entonces puede suponer que el usuario desea expandir la fila y continuar con esa acción ...

OMI, deberías volver a pensar esto. Por desgracia, un manejador de un solo clic no puede saber si el usuario está a punto de hacer doble clic.

Sugiero hacer ambas acciones con un solo clic, y simplemente no propagar desde el campo editable cuando se hace clic.


Escribí un plugin jQuery simple que le permite usar un evento personalizado ''singleclick'' para diferenciar un solo clic de un doble clic. Esto le permite construir una interfaz donde un solo clic hace que la entrada sea editable, mientras que un doble clic la expande. Al igual que el sistema de archivos de Windows / OSX renombrar / abrir la interfaz de usuario.

https://github.com/omriyariv/jquery-singleclick

$(''#someInput'').on(''singleclick'', function(e) { // The event will be fired with a small delay but will not fire upon a double-click. makeEditable(e.target); } $(''#container'').on(''dblclick'', function(e) { // Expand the row... }


Este ejemplo en vainilla javascript debería funcionar:

var timer = 0 var delay = 200 var prevent = false node.onclick = (evnt) => { timer = setTimeout(() => { if(!prevent){ //Your code } prevent = false }, delay) } node.ondblclick = (evnt) => { clearTimeout(timer) prevent=true //Your code }


Hay una forma más elegante de manejar este problema si estás utilizando backbonejs:

initialize: function(){ this.addListener_openWidget(); } addListener_openWidget: function(){ this.listenToOnce( this, ''openWidgetView'', function(e){this.openWidget(e)} ); }, events: { ''click #openWidgetLink'' : function(e){this.trigger(''openWidgetView'',e)}, ''click #closeWidgetLink'' : ''closeWidget'' }, openWidget: function( e ){ //Do your stuff }, closeWidget: function(){ this.addListener_openWidget(); }


La idea general:

  1. Tras el primer clic, no llame a la función asociada (digamos single_click_function ()). Más bien, configure un temporizador por un cierto período de tiempo (digamos x). Si no recibimos otro clic durante ese lapso de tiempo, busque la función single_click_function (). Si obtenemos uno, llame a double_click_function ()

  2. El temporizador se borrará una vez que se reciba el segundo clic. También se borrará una vez transcurridos x milisegundos.

Por cierto, verifique la respuesta de Paolo: ¡ Necesito cancelar los eventos de clic / ratón al hacer doble clic en el evento detectado y, por supuesto, en todo el hilo! :-)

Mejor respuesta: https://.com/a/7845282/260610


Vuelva a escribir la respuesta del usuario822711 para su reutilización:

$.singleDoubleClick = function(singleClk, doubleClk) { return (function() { var alreadyclicked = false; var alreadyclickedTimeout; return function(e) { if (alreadyclicked) { // double alreadyclicked = false; alreadyclickedTimeout && clearTimeout(alreadyclickedTimeout); doubleClk && doubleClk(e); } else { // single alreadyclicked = true; alreadyclickedTimeout = setTimeout(function() { alreadyclicked = false; singleClk && singleClk(e); }, 300); } } })(); }

Llamar a la función.

$(''td.dblclickable'').bind(''click'', $.singleDoubleClick(function(e){ //click. }, function(e){ //double click. });


Demostración de trabajo

$(''#alreadyclicked'').val(''no click''); $(''td.dblclickable'').on(''click'',function(){ var $button=$(this); if ($button.data(''alreadyclicked'')){ $button.data(''alreadyclicked'', false); // reset $(''#alreadyclicked'').val(''no click''); if ($button.data(''alreadyclickedTimeout'')){ clearTimeout($button.data(''alreadyclickedTimeout'')); // prevent this from happening } // do what needs to happen on double click. $(''#action'').val(''Was double clicked''); }else{ $button.data(''alreadyclicked'', true); $(''#alreadyclicked'').val(''clicked''); var alreadyclickedTimeout=setTimeout(function(){ $button.data(''alreadyclicked'', false); // reset when it happens $(''#alreadyclicked'').val(''no click''); $(''#action'').val(''Was single clicked''); // do what needs to happen on single click. // use $button instead of $(this) because $(this) is // no longer the element },300); // <-- dblclick tolerance here $button.data(''alreadyclickedTimeout'', alreadyclickedTimeout); // store this id to clear if necessary } return false; });

obviamente use <td class="dblclickable">


window.UI = { MIN_LAPS_FOR_DBL_CLICK: 200, // msecs evt_down:null, timer_down:null, mousedown:function(evt){ if( this.evt_down && evt.timeStamp < this.evt_down.timeStamp + this.MIN_LAPS_FOR_DBL_CLICK ){ clearTimeout(this.timer_down); this.double_click(evt); // => double click } else { this.evt_down = evt; this.timer_down = setTimeout("UI.do_on_mousedown()", this.MIN_LAPS_FOR_DBL_CLICK); } }, evt_up:null, timer_up:null, mouseup:function(evt){ if( this.evt_up && evt.timeStamp < this.evt_up.timeStamp + this.MIN_LAPS_FOR_DBL_CLICK ){ clearTimeout(this.timer_up); } else { this.evt_up = evt; this.timer_up = setTimeout("UI.do_on_mouseup()", this.MIN_LAPS_FOR_DBL_CLICK); } }, do_on_mousedown:function(){ var evt = this.evt_down; // Treatment MOUSE-DOWN here }, do_on_mouseup:function(){ var evt = this.evt_up; // Treatment MOUSE-UP here }, double_click:function(evt){ // Treatment DBL-CLICK here } } // Then the observers $(''div#myfoo'').bind(''mousedown'', $.proxy(UI.mousedown, UI)); $(''div#myfoo'').bind(''mouseup'', $.proxy(UI.mouseup, UI));