Jquery vincular clique duplo e clique único separadamente

96

Existe algo no jquery que me permite diferenciar entre o comportamento de clique duplo e clique único?

Quando eu vinculo ambos ao mesmo elemento, apenas um único clique é executado.

Existe uma maneira de esperar algum tempo antes da execução do único clique para ver se o usuário clica novamente ou não?

Obrigado :)

Kritya
fonte

Respostas:

143

Descobri que a resposta de John Strickler não fez exatamente o que eu esperava. Depois que o alerta é disparado por um segundo clique na janela de dois segundos, cada clique subsequente dispara outro alerta até que você espere dois segundos antes de clicar novamente. Assim, com o código de John, um clique triplo atua como dois cliques duplos, onde eu esperaria que atuasse como um clique duplo seguido por um único clique.

Retrabalhei sua solução para funcionar dessa maneira e fluir de uma forma que minha mente possa compreender melhor. Eu diminuí o atraso de 2.000 para 700 para simular melhor o que eu consideraria uma sensibilidade normal. Aqui está o violino: http://jsfiddle.net/KpCwN/4/ .

Obrigado pela fundação, John. Espero que esta versão alternativa seja útil para outras pessoas.

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
fonte
1
Use .delegate () sobre .live () embora.
John Strickler
23
use .on()sobre ambos agora
Claudiu
2
O uso desta solução atrasa o evento de clique em 700 ms! É muito irritante para o usuário ...
uriel
1
@uriel, se você acha que 700 ms é muito tempo para esperar por um clique duplo, apenas diminua o número até que se adapte às suas preferências.
Garland Pope
1
a partir do jQuery 1.7: para oferecer suporte ao conteúdo carregado posteriormente (material ajax), use $("document").on("click","a" function(e){em vez disso na linha 5. Esta construção substitui o delegate()uso obsoleto . Em vez de documentvocê pode / deve usar qualquer objeto pai ado DOM, tanto quanto possível, que persiste no tempo.
Hafenkranich de
15

A solução fornecida por "Nott Responding" parece disparar ambos os eventos, clique e dblclick quando clicado duas vezes. No entanto, acho que aponta na direção certa.

Fiz uma pequena mudança, este é o 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);          
    }
});

Tente

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

calterras
fonte
10

Claro, vincule dois manipuladores, um a clicke outro a dblclick. Crie uma variável que aumenta a cada clique. então reinicia após um atraso definido. Dentro da função setTimeout você pode fazer 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
fonte
Muito obrigado. Tentei adicionar o if (cliques == 1), mas não foi possível adicionar a função de clique único. Mais uma vez, obrigado :)
kritya
@kritya Eu editei minha resposta - isso deve funcionar melhor para você. Veja o violino aqui - jsfiddle.net/VfJU4/1
John Strickler
OOOOh eu cheguei onde estava errado, eu não coloquei ',' ser viciado em dreamweaver não destacou: P wtv Obrigado :)
kritya
9

Você provavelmente poderia escrever sua própria implementação customizada de click / dblclick para que ela espere por um clique extra. Não vejo nada nas funções principais do jQuery que ajudem você a conseguir isso.

Citação de .dblclick () no site jQuery

Não é aconselhável vincular os manipuladores aos eventos click e dblclick para o mesmo elemento. A sequência de eventos disparados varia de navegador para navegador, alguns recebendo dois eventos de clique antes do dblclick e outros apenas um. A sensibilidade do clique duplo (tempo máximo entre os cliques detectado como um clique duplo) pode variar de acordo com o sistema operacional e o navegador, e geralmente é configurável pelo usuário.

Mick Hansen
fonte
4

Observe o seguinte 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
});

A demonstração vai aqui http://jsfiddle.net/cB484/

Muhammad Tahir
fonte
4
Gosto da sua ideia de adicionar classe e usá-la como uma contagem.
nikhil
se você adicionar Alert (); em vez de // seu código para clique único, ele não está funcionando de jeito nenhum
Desenvolvedor de
4

Eu escrevi um plugin jQuery que permite também delegar os eventos click e 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
fonte
Este plugin é ótimo! Mas de alguma forma ele não parece funcionar no IE9? Não ligo para versões mais antigas (e você não deveria mais hoje em dia IMO), mas tento alcançar a funcionalidade pelo menos no IE9 - este é o navegador que qualquer um pode ter (sem limitações de sistema operacional) e que tem um bom suporte a JS.
Dennis98
Uso:$("body").multipleClicks('#mySelector', function(){ /* do something on click */},function(){/* do something on doubleclick */},300);
Hafenkranich de
Na verdade, este permite que você use ambos - clique e clique duas vezes - ao mesmo tempo para diferentes ações. Obrigado! Esse funciona como um encanto.
Hafenkranich de
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
fonte
Simples e eficaz. +1
Bruce Pierson
3

estou implementando esta solução simples, http://jsfiddle.net/533135/VHkLR/5/
código html

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

código de script

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


não é muito lento

Chetan Sandeep Renu
fonte
2

Esta solução funciona para mim

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
fonte
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);

E, finalmente, usamos como.

$("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
fonte
Qual é a diferença entre $ .click e $ .fn.click?
FrenkyB,
0

Igual à resposta acima, mas permite o clique triplo. (Atraso 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
fonte
0

Este é um método que você pode fazer usando o JavaScript básico, que funciona para mim:

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");
}
user3781586
fonte
0

Abaixo está minha abordagem simples para o problema.

Função 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);
    });
}

Implementação:

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

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

Inspecione o elemento clicado no Firefox / Chrome para ver os cliques de dados sobem e descem conforme você clica, ajuste o tempo (1000) para se adequar.

mhapps
fonte