2009-05-19 5 views
21

Я обрабатываю событие click и dblclick на элементе DOM. Каждый из них выполняет другую команду, но я обнаружил, что при двойном щелчке по элементу, помимо запуска события двойного щелчка, событие click также запускается дважды. Каков наилучший подход для предотвращения такого поведения?Предотвратить событие щелчка при стрельбе, когда происходит событие dblclick

ответ

11

В комментарии, вы сказали,

замедлю обработчик щелчка на 300 мс (заметно и раздражает задержки) и даже ...

Так это звучит как то, что вы хотите заключается в том, что когда вы нажимаете, DOM должен немедленно генерировать событие щелчка, за исключением того, что щелчок является первым щелчком двойного щелчка.

Для реализации этой функции, когда вы нажимаете кнопку, DOM должен быть в состоянии предсказать, является ли это последним кликом или является ли это первым из двойного щелчка (однако я не думаю, что это возможно вообще для DOM, чтобы предсказать, собирается ли пользователь снова щелкнуть).


Каковы два разных действия, которые вы пытаетесь сделать одним щелчком мыши и дважды щелкнуть? IMO, в обычном приложении вам могут потребоваться оба события: например. один клик, чтобы сфокусироваться на элементе, а затем дважды щелкните, чтобы активировать его.

Когда вы должны разделить события, некоторые приложения используют что-то другое, кроме двойного щелчка: например, они используют щелчок правой кнопкой мыши или щелчок по кнопке управления.

+0

Спасибо за обновленный ответ. Я думаю, что это действительно сводится к тому, что мне нужно переосмыслить свой интерфейс. То, чего я хочу достичь, не будет возможным. Я должен просто использовать два элемента управления для двух действий или использовать ключ-модификатор вместо двойного щелчка. Благодаря! – David

5

В этом случае лучше задержать выполнение события с одним кликом. Попросите обработчик двойного щелчка установить переменную, которую проверит событие с одним кликом. Если эта переменная имеет конкретное значение, может быть boolDoubleClick == true, тогда не нужно fire/handle за один клик.

+0

Фактически, это то, что я сейчас делаю, но похоже, что это довольно неприятное решение. Я задерживаю обработчик кликов на 300 мс (заметная и раздражающая задержка), и даже с этим вы можете удвоить клик достаточно медленно (например, 350 мс), чтобы оба они срабатывали. – David

+0

Интересно. Неразумно предположить, что если они задерживаются слишком долго для второго щелчка, то желаемый эффект будет равным двум кликам. –

+0

К сожалению, время двойного щелчка настраивается конечным пользователем (например, с помощью панели управления/мыши), и я полагаю, что JavaScript в браузере не может получить/определить, на что настроена эта временная задержка. – ChrisW

3

AFAIK DOM Level 2 Events не дает никаких спецификаций для двойного щелчка. Это не работает для меня на IE7 (есть шок), но у FF и Opera нет проблем с управлением спецификацией, где я могу прикрепить все действия к событию click, но для двойного щелчка просто дождитесь, пока "деталь" атрибут объекта события - 2. Из документов: «Если несколько кликов происходят в одном и том же месте экрана, последовательность повторяется с дополнительным атрибутом детали с каждым повторением».

+0

Это на самом деле очень элегантное решение проблемы. Он по-прежнему требует компиляции setTimout/clearTimeout для первого щелчка, но он упрощает координацию между ними и даже открывает дверь для тройных щелчков и т. Д. Спасибо! – mckamey

2

Спасибо всех других ответов здесь, как комбинация из них, кажется, обеспечивает разумное решение для меня, когда взаимодействие требует оба, но взаимоисключающее:

var pendingClick = 0; 

function xorClick(e) { 
    // kill any pending single clicks 
    if (pendingClick) { 
     clearTimeout(pendingClick); 
     pendingClick = 0; 
    } 

    switch (e.detail) { 
     case 1: 
      pendingClick = setTimeout(function() { 
       console.log('single click action here'); 
      }, 500);// should match OS multi-click speed 
      break; 
     case 2: 
      console.log('double click action here'); 
      break; 
     default: 
      console.log('higher multi-click actions can be added as needed'); 
      break; 
    } 
} 

myElem.addEventListener('click', xorClick, false); 

Update: Я добавил обобщенную версию этого подхода наряду с щелчком polyfill для сенсорных устройств к этому Github репозиторий с примерами:

https://github.com/mckamey/doubleTap.js

2

Вот что я сделал disting uish в модуле

 node.on('click', function(e) { 

      //Prepare for double click, continue to clickHandler doesn't come soon enough 
      console.log("cleared timeout in click",_this.clickTimeout); 
      clearTimeout(_this.clickTimeout); 
      _this.clickTimeout = setTimeout(function(){ 
       console.log("handling click"); 
       _this.onClick(e); 
      },200); 
      console.log(_this.clickTimeout); 
     }); 

     node.on('dblclick', function (e) { 

      console.log("cleared timeout in dblclick",_this.clickTimeout); 
      clearTimeout(_this.clickTimeout); 
      // Rest of the handler function 
11

В случае, если кто-либо еще натыкается на это (как я) искал ответ, то самое лучшее решение, которое я мог придумать следующий:

$node.on('click',function(e){ 
     if(e.originalEvent.detail > 1){ 
     return; 
     /* if you are returning a value from this 
     function then return false or cancel 
     the event some other way */ 
     } 
    }); 

Готово.Если имеется более одного щелчка назад, второй, третий и т. Д. не будет срабатывать. Я определенно предпочитаю использовать любые таймеры.

Я указал себе в этом направлении, прочитав this.


Кстати: я был первым исследованием этой проблемы, потому что я случайно нажал дважды постраничного ссылку, а событие уволен и закончил два раза до обратного вызова может произойти.

Перед приездом с кодом выше, я имел

if e.originalEvent.detail === 2 //return 

однако, я был в состоянии нажать на ссылку в 3 раза (тройной клик), и хотя второй щелчок Ждут» t огонь, третий сделал

+0

Это предотвратит 2-й щелчок от стрельбы и все-таки позволит выстрелить 1-го щелчка. OP хотел отключить 1-й щелчок, если есть 2-й щелчок, если я правильно понимаю. Я считаю, что лучше всего использовать небольшую задержку (я использую 200 мс, но надеялся, что есть лучшее решение, которое я просто не мог видеть). – ClarkeyBoy

+0

@ ClarkeyBoy - вы ошибаетесь. Это отключит первый щелчок, если есть секунда. Попробуй. – user1167442

+5

Не работает в IE 11 x64 (Win8.1): event.detail = 0 всегда, один или два раза – robert4

0

Я знаю, что это старый, как черт, но думал, что я опубликую так или иначе, так как я просто столкнулся с той же проблемой. Вот как я это разрешил.

$('#alerts-display, #object-display').on('click', ['.item-data-summary', '.item-marker'], function(e) { 
    e.preventDefault(); 

    var id; 

    id = setTimeout(() => { 
     // code to run here 
     return false; 
    }, 150); 

    timeoutIDForDoubleClick.push(id); 
}); 


$('.panel-items-set-marker-view').on('dblclick', ['.summary', '.marker'], function(e) { 
    for (let i = 0; i < timeoutIDForDoubleClick.length; i++) { 
     clearTimeout(timeoutIDForDoubleClick[i]); 
    } 

    // code to run on double click 

    e.preventDefault(); 
}); 
Смежные вопросы