Jquery enlaza doble clic y un solo clic por separado

96

¿Hay algo en jquery que me permita diferenciar el comportamiento al hacer doble clic y al hacer un solo clic?

Cuando enlazo ambos al mismo elemento, solo se ejecuta el clic único.

¿Hay alguna forma de esperar un tiempo antes de la ejecución del clic único para ver si el usuario vuelve a hacer clic o no?

Gracias :)

Kritya
fuente

Respuestas:

143

Descubrí que la respuesta de John Strickler no cumplía con lo que esperaba. Una vez que la alerta se activa con un segundo clic dentro de la ventana de dos segundos, cada clic posterior activa otra alerta hasta que espere dos segundos antes de volver a hacer clic. Entonces, con el código de John, un triple clic actúa como dos dobles clics donde esperaría que actuara como un doble clic seguido de un solo clic.

He reelaborado su solución para que funcione de esta manera y fluya de una manera que mi mente pueda comprender mejor. Bajé el retardo de 2000 a 700 para simular mejor lo que sentiría como una sensibilidad normal. Aquí está el violín: http://jsfiddle.net/KpCwN/4/ .

Gracias por la fundación, John. Espero que esta versión alternativa sea útil para otros.

var DELAY = 700, clicks = 0, timer = null;

$(function(){

    $("a").on("click", function(e){

        clicks++;  //count clicks

        if(clicks === 1) {

            timer = setTimeout(function() {

                alert("Single Click");  //perform single-click action    
                clicks = 0;             //after action performed, reset counter

            }, DELAY);

        } else {

            clearTimeout(timer);    //prevent single-click action
            alert("Double Click");  //perform double-click action
            clicks = 0;             //after action performed, reset counter
        }

    })
    .on("dblclick", function(e){
        e.preventDefault();  //cancel system double-click event
    });

});
Papa Garland
fuente
1
Sin embargo, use .delegate () sobre .live ().
John Strickler
23
usar .on()sobre ambos ahora
Claudiu
2
El uso de esta solución retrasa el evento de clic en 700 ms. Es muy molesto para el usuario ...
Uriel
1
@uriel, si cree que 700 ms es demasiado tiempo para esperar un doble clic, reduzca el número hasta que se adapte a sus preferencias.
Garland Pope
1
a partir de jQuery 1.7: para admitir contenido cargado posteriormente (cosas ajax), utilice $("document").on("click","a" function(e){en su lugar en la línea 5. Esta construcción reemplaza el delegate()uso obsoleto . En lugar de document, puede / debe usar cualquier objeto principal adel DOM en la medida de lo posible que persista durante el tiempo.
Hafenkranich
15

La solución dada por "Nott Responding" parece disparar ambos eventos, haga clic y haga doble clic cuando se haga doble clic. Sin embargo, creo que apunta en la dirección correcta.

Hice un pequeño cambio, este es el resultado:

$("#clickMe").click(function (e) {
    var $this = $(this);
    if ($this.hasClass('clicked')){
        $this.removeClass('clicked'); 
        alert("Double click");
        //here is your code for double click
    }else{
        $this.addClass('clicked');
        setTimeout(function() { 
            if ($this.hasClass('clicked')){
                $this.removeClass('clicked'); 
                alert("Just one click!");
                //your code for single click              
            }
        }, 500);          
    }
});

Intentalo

http://jsfiddle.net/calterras/xmmo3esg/

calterras
fuente
10

Claro, vincule a dos manipuladores, uno a clicky otro a dblclick. Cree una variable que se incremente con cada clic. luego se reinicia después de un retraso establecido. Dentro de la función setTimeout puedes hacer algo ...

var DELAY = 2000,
    clicks = 0,
    timer = null;

$('a').bind({
    click: function(e) {
        clearTimeout(timer);

        timer = setTimeout(function() {
            clicks = 0;
        }, DELAY);

        if(clicks === 1) {
            alert(clicks);
             //do something here

            clicks = 0;
        }

        //Increment clicks
        clicks++;
    },
    dblclick: function(e) {
        e.preventDefault(); //don't do anything
    }
});
John Strickler
fuente
Muchas gracias. Intenté agregar el if (clics == 1) pero no puedo. Por favor, agregue la función de un solo clic. Nuevamente gracias :)
kritya
@kritya Edité mi respuesta; esto debería funcionar mejor para ti. Vea el violín aquí - jsfiddle.net/VfJU4/1
John Strickler
Ooooh tengo donde yo estaba equivocado que no tuve que poner '' ser adicto a Dreamweaver que aún no ha puesto de manifiesto que: P wtv Gracias :)
kritya
9

Probablemente podría escribir su propia implementación personalizada de click / dblclick para que espere un clic adicional. No veo nada en las funciones principales de jQuery que lo ayuden a lograr esto.

Cita de .dblclick () en el sitio de jQuery

No es aconsejable vincular controladores a los eventos click y dblclick para el mismo elemento. La secuencia de eventos desencadenados varía de un navegador a otro, algunos reciben dos eventos de clic antes del dblclick y otros solo uno. La sensibilidad del doble clic (tiempo máximo entre los clics que se detecta como un doble clic) puede variar según el sistema operativo y el navegador, y a menudo es configurable por el usuario.

Mick Hansen
fuente
4

Mira el siguiente código

$("#clickMe").click(function (e) {
    var $this = $(this);
    if ($this.hasClass('clicked')){
        alert("Double click");
        //here is your code for double click
        return;
    }else{
         $this.addClass('clicked');
        //your code for single click
         setTimeout(function() { 
                 $this.removeClass('clicked'); },500);
    }//end of else
});

La demostración va aquí http://jsfiddle.net/cB484/

Muhammad Tahir
fuente
4
Me gusta tu idea de agregar una clase y usarla como recuento.
nikhil
si agrega Alerta (); en lugar de // su código para un solo clic, no funciona en absoluto
Desarrollador
4

Escribí un complemento de jQuery que también permite delegar los eventos de clic y dblclick

// jQuery plugin to bind both single and double click to objects
// parameter 'delegateSelector' is optional and allow to delegate the events
// parameter 'dblclickWait' is optional default is 300
(function($) {
$.fn.multipleClicks = function(delegateSelector, clickFun, dblclickFun, dblclickWait) {
    var obj;
    if (typeof(delegateSelector)==='function' && typeof(clickFun)==='function') {
        dblclickWait = dblclickFun; dblclickFun = clickFun; clickFun = delegateSelector; delegateSelector = null; // If 'delegateSelector' is missing reorder arguments
    } else if (!(typeof(delegateSelector)==='string' && typeof(clickFun)==='function' && typeof(dblclickFun)==='function')) {
        return false;
    }
    return $(this).each(function() {
        $(this).on('click', delegateSelector, function(event) {
            var self = this;
            clicks = ($(self).data('clicks') || 0)+1;
            $(self).data('clicks', clicks);
            if (clicks == 1) {
                setTimeout(function(){
                    if ($(self).data('clicks') == 1) {
                        clickFun.call(self, event); // Single click action
                    } else {
                        dblclickFun.call(self, event); // Double click action
                    }
                    $(self).data('clicks', 0);
                }, dblclickWait || 300);
            }
        });
    });
};
})(jQuery);
IlNidoDelChiurlo
fuente
¡Este complemento es genial! ¿Pero de alguna manera no parece funcionar en IE9? No me importan las versiones anteriores (y hoy en día ya no debería, en mi opinión), pero trato de lograr la funcionalidad al menos en IE9: este es el navegador que cualquiera puede tener (sin limitaciones del sistema operativo) y que tiene un buen soporte JS.
Dennis98
Uso:$("body").multipleClicks('#mySelector', function(){ /* do something on click */},function(){/* do something on doubleclick */},300);
Hafenkranich
En realidad, este le permite usar ambos (hacer clic y hacer doble clic) al mismo tiempo para diferentes acciones. ¡Gracias! Ese funciona de maravilla.
Hafenkranich
3
var singleClickTimer = 0; //define a var to hold timer event in parent scope
jqueryElem.click(function(e){ //using jquery click handler
    if (e.detail == 1) { //ensure this is the first click
        singleClickTimer = setTimeout(function(){ //create a timer
            alert('single'); //run your single click code
        },250); //250 or 1/4th second is about right
    }
});

jqueryElem.dblclick(function(e){ //using jquery dblclick handler
    clearTimeout(singleClickTimer); //cancel the single click
    alert('double'); //run your double click code
});
Gregory Ray
fuente
Simple y eficaz. +1
Bruce Pierson
3

Estoy implementando esta solución simple, http://jsfiddle.net/533135/VHkLR/5/
código html

<p>Click on this paragraph.</p>
<b> </b>

código de secuencia de comandos

var dbclick=false;    
$("p").click(function(){
setTimeout(function(){
if(dbclick ==false){
$("b").html("clicked")
}

},200)

}).dblclick(function(){
dbclick = true
$("b").html("dbclicked")
setTimeout(function(){
dbclick = false


},300)
});


no es mucho laggy

Chetan Sandeep Renu
fuente
2

Esta solución funciona para mi

var DELAY = 250, clicks = 0, timer = null;

$(".fc-event").click(function(e) {
    if (timer == null) {
        timer = setTimeout(function() {
           clicks = 0;
            timer = null;
            // single click code
        }, DELAY);
    }

    if(clicks === 1) {
         clearTimeout(timer);
         timer = null;
         clicks = -1;
         // double click code
    }
    clicks++;
});
Vitali Korol
fuente
0
(function($){

$.click2 = function (elm, o){
    this.ao = o;
    var DELAY = 700, clicks = 0;
    var timer = null;
    var self = this;

    $(elm).on('click', function(e){
        clicks++;
        if(clicks === 1){
            timer = setTimeout(function(){
                self.ao.click(e);
            }, DELAY);
        } else {
            clearTimeout(timer);
            self.ao.dblclick(e);
        }
    }).on('dblclick', function(e){
        e.preventDefault();
    });

};

$.click2.defaults = { click: function(e){}, dblclick: function(e){} };

$.fn.click2 = function(o){
    o = $.extend({},$.click2.defaults, o);
    this.each(function(){ new $.click2(this, o); });
    return this;
};

})(jQuery);

Y finalmente usamos as.

$("a").click2({
    click : function(e){
        var cid = $(this).data('cid');
        console.log("Click : "+cid);
    },
    dblclick : function(e){
        var cid = $(this).data('cid');
        console.log("Double Click : "+cid);
    }
});
Sergio FG
fuente
¿Cuál es la diferencia entre $ .click y $ .fn.click?
FrenkyB
0

Igual que la respuesta anterior, pero permite un triple clic. (Retraso 500) http://jsfiddle.net/luenwarneke/rV78Y/1/

    var DELAY = 500,
    clicks = 0,
    timer = null;

$(document).ready(function() {
    $("a")
    .on("click", function(e){
        clicks++;  //count clicks
        timer = setTimeout(function() {
        if(clicks === 1) {
           alert('Single Click'); //perform single-click action
        } else if(clicks === 2) {
           alert('Double Click'); //perform single-click action
        } else if(clicks >= 3) {
           alert('Triple Click'); //perform Triple-click action
        }
         clearTimeout(timer);
         clicks = 0;  //after action performed, reset counter
       }, DELAY);
    })
    .on("dblclick", function(e){
        e.preventDefault();  //cancel system double-click event
    });
});
Luen
fuente
0

Este es un método que puede hacer usando el JavaScript básico, que funciona para mí:

var v_Result;
function OneClick() {
    v_Result = false;
    window.setTimeout(OneClick_Nei, 500)
    function OneClick_Nei() {
        if (v_Result != false) return;
        alert("single click");
    }
}
function TwoClick() {
    v_Result = true;
    alert("double click");
}
usuario3781586
fuente
0

A continuación se muestra mi enfoque simple del problema.

Función JQuery:

jQuery.fn.trackClicks = function () {
    if ($(this).attr("data-clicks") === undefined) $(this).attr("data-clicks", 0);

    var timer;
    $(this).click(function () {
        $(this).attr("data-clicks", parseInt($(this).attr("data-clicks")) + 1);

        if (timer) clearTimeout(timer);

        var item = $(this);
        timer = setTimeout(function() {
            item.attr("data-clicks", 0);
        }, 1000);
    });
}

Implementación:

$(function () {
    $("a").trackClicks();

    $("a").click(function () {
        if ($(this).attr("data-clicks") === "2") {
            // Double clicked
        }
    });
});

Inspeccione el elemento en el que se hizo clic en Firefox / Chrome para ver que los clics de datos suben y bajan a medida que hace clic, ajuste el tiempo (1000) para que se adapte.

mhapps
fuente