Jquery прив'язує подвійне клацання та один клік окремо


96

Чи є щось у jquery, що дозволило б мені розрізняти поведінку при подвійному клацанні та одному кліку?

Коли я прив'язую обидва до одного елемента, виконується лише один клік.

Чи є спосіб зачекати деякий час перед виконанням одного клацання, щоб побачити, клацне користувач ще раз чи ні?

Дякую :)


Відповіді:


143

Я виявив, що відповідь Джона Стріклера не зовсім відповідає тому, що я очікував. Як тільки попередження спрацьовує другим клацанням у двосекундному вікні, кожне наступне клацання спрацьовує ще одне сповіщення, поки ви не зачекаєте дві секунди, перш ніж клацнути ще раз. Отже, з кодом Джона потрійний клік діє як два подвійні клацання, де я очікував би, що він діятиме як подвійний клацання, за яким слідує один клік.

Я переробив його рішення, щоб функціонувати таким чином і текти так, щоб мій розум міг краще зрозуміти. Я зменшив затримку з 2000 до 700, щоб краще імітувати те, що я відчував би як нормальну чутливість. Ось скрипка: http://jsfiddle.net/KpCwN/4/ .

Дякую за основу, Джон. Сподіваюсь, ця альтернативна версія корисна іншим.

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

});

1
Використовуйте .delegate () над .live ().
Джон Стріклер

23
використовувати .on()над обома з них зараз
Клавдіу

2
Використання цього рішення затримує подію натискання на 700 мс! Користувача це дуже дратує ...
uriel

1
@uriel, якщо ти вважаєш, що 700 мс занадто довго, щоб чекати подвійного клацання, просто зменши число, поки воно не відповідатиме твоїм уподобанням.
Гарленд Папа

1
станом на jQuery 1.7: Для підтримки пізніше завантаженого вмісту (матеріали ajax) використовуйте $("document").on("click","a" function(e){замість цього рядок 5. Ця конструкція замінює застаріле delegate()використання. Замість цього documentви можете / повинні використовувати будь-який батьківський об'єкт aвниз DOM, наскільки це можливо, який зберігається протягом часу.
Гафенкраніч

15

Рішення, надане "Nott Responding", схоже, запускає обидві події, клацання та dblclick при подвійному клацанні. Однак я думаю, що це вказує у правильному напрямку.

Я зробив невелику зміну, ось результат:

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

Спробуй це

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


10

Звичайно, прив’яжіть двох обробників, одного до, clickа іншого до dblclick. Створіть змінну, яка збільшується при кожному клацанні. потім скидає після встановленої затримки. Усередині функції setTimeout ви можете щось зробити ...

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

Дуже дякую. Я спробував додати if (кліки == 1), але це не вдалося, будь ласка, додайте функцію одного клацання. Ще раз спасибі :)
kritya

@kritya Я відредагував свою відповідь - це має працювати краще для вас. Дивіться скрипку тут - jsfiddle.net/VfJU4/1
Джон Стріклер

OOOOh I got where I was wrong I did not put that ',' being addicted to dreamweaver it did not светла це: P wtv Спасибі :)
kritya

9

Можливо, ви можете написати власну реалізацію click / dblclick, щоб вона зачекала на додатковий клік. Я не бачу в основних функціях jQuery нічого, що допомогло б вам досягти цього.

Цитата з .dblclick () на сайті jQuery

Не рекомендується прив'язувати обробники до подій click і dblclick для одного і того ж елемента. Послідовність ініційованих подій залежить від браузера до браузера, при цьому деякі отримують дві події клацання перед dblclick, а інші лише одну. Чутливість подвійного клацання (максимальний час між клацаннями, який виявляється як подвійне клацання) може відрізнятися залежно від операційної системи та браузера і часто може бути налаштована користувачем.


4

Подивіться на наступний код

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

Демо-версія тут http://jsfiddle.net/cB484/


4
мені подобається ваша ідея додати клас і використовувати його як підрахунок.
nikhil

якщо ви додасте Alert (); замість // ваш код для одного клацання він взагалі не працює
розробник

4

Я написав плагін jQuery, який дозволяє також делегувати події click і 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);

Цей плагін чудовий! Але якось це, здається, не працює в IE9? Мені байдужі старіші версії (і сьогодні вам більше не потрібно IMO), але я намагаюся досягти функціональності принаймні на IE9 - це браузер, який може бути у кожного (без обмежень ОС), і який має хорошу підтримку JS.
Dennis98

Використання:$("body").multipleClicks('#mySelector', function(){ /* do something on click */},function(){/* do something on doubleclick */},300);
Хафенкраніч,

Цей фактично дозволяє одночасно використовувати обидва - клацання та подвійне клацання - для різних дій. Дякую! Цей працює як шарм.
Гафенкраніч

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

Простий та ефективний. +1
Брюс Пірсон,

3

я впроваджую це просте рішення, http://jsfiddle.net/533135/VHkLR/5/
html код

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

код сценарію

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


це не набагато відстало


2

Це рішення працює для мене

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


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

І нарешті ми використовуємо як.

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

У чому різниця між $ .click і $ .fn.click?
FrenkyB

0

Те саме, що і відповідь вище, але дозволяє тричі клацнути. (Затримка 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
    });
});

0

Це метод, який ви можете зробити, використовуючи базовий JavaScript, який працює для мене:

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

0

Нижче мій простий підхід до цього питання.

Функція 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);
    });
}

Реалізація:

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

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

Перевірте елемент, на якому клацнули, у Firefox / Chrome, щоб побачити, як клацання даних рухаються вгору та вниз, коли ви клацаєте, відрегулюйте час (1000) відповідно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.