Подтвердить что ты не робот

Как использовать как onclick, так и ondblclick для элемента?

У меня есть элемент на моей странице, для которого мне нужно привязать обработчики событий onclick и ondblclick. Когда происходит один клик, он должен делать что-то другое, чем двойной щелчок. Когда я впервые начал делать эту работу, моя голова начала вращаться. Очевидно, что onclick всегда будет срабатывать при двойном щелчке. Поэтому я попытался использовать структуру, основанную на тайм-ауте, такую ​​как...

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  el.onclick = function() {
    timer = setTimeout(function() { alert('Single'); }, 150);        
  }

  el.ondblclick = function() {
    clearTimeout(timer);
    alert('Double');
  }
}

Но у меня были несогласованные результаты (с использованием IE8). Он работал бы много раз, но иногда я получал предупреждение "Single" два раза.

Кто-нибудь сделал это раньше? Есть ли более эффективный способ?

4b9b3361

Ответ 1

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

el.onclick = function() {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() { alert('Single'); }, 250);        
}

Таким образом, если клик уже установлен, он очистится, чтобы избежать дублирования предупреждений "Single".

Ответ 2

Если вы получаете 2 предупреждения, кажется, ваш порог для обнаружения двойного щелчка слишком мал. Попробуйте увеличить от 150 до 300 мс.

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

Я вижу два возможных решения этой потенциальной проблемы:

1) Установите другой тайм-аут для фактического запуска события двойного щелчка. Отметьте в своем коде, что событие двойного щелчка собирается запустить. Затем, когда срабатывает событие "один клик", он может проверить это состояние и сказать "oops, dbl click pending, поэтому я ничего не сделаю"

2) Второй вариант заключается в замене ваших целевых функций на основе событий щелчка. Это может выглядеть примерно так:

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  var firing = false;
  var singleClick = function(){
    alert('Single');
  };

  var doubleClick = function(){ 
    alert('Double');
  };

  var firingFunc = singleClick;

  el.onclick = function() {
    // Detect the 2nd single click event, so we can stop it
    if(firing) 
      return;

    firing = true;
    timer = setTimeout(function() { 
       firingFunc(); 

       // Always revert back to singleClick firing function
       firingFunc = singleClick;
       firing = false;
    }, 150);

  }

  el.ondblclick = function() {
    firingFunc = doubleClick; 
    // Now, when the original timeout of your single click finishes, 
    // firingFunc will be pointing to your doubleClick handler        
  }
}

В основном, что происходит здесь, вы можете оставить исходный тайм-аут, который вы установили. Он всегда будет называть firingFunc(); Единственное, что меняется, это то, что на самом деле указывает firingFunc(). Как только двойной клик обнаружен, он устанавливает его в doubleClick. И тогда мы всегда возвращаемся к singleClick, когда истекает время ожидания.

У нас также есть переменная "стрельба", поэтому мы знаем, чтобы перехватить второе событие с одним кликом.

Другая альтернатива - полностью игнорировать события dblclick и просто обнаруживать ее с помощью одиночных кликов и таймера:

window.onload = function() {
  var timer;
  var el = document.getElementById('testButton');

  var firing = false;
  var singleClick = function(){
    alert('Single');
  };

  var doubleClick = function(){ 
    alert('Double');
  };

  var firingFunc = singleClick;

  el.onclick = function() {
    // Detect the 2nd single click event, so we can set it to doubleClick
    if(firing){
      firingFunc = doubleClick; 
      return;
    }

    firing = true;
    timer = setTimeout(function() { 
       firingFunc(); 

       // Always revert back to singleClick firing function
       firingFunc = singleClick;
       firing = false;
    }, 150);

  }
}

Это не проверено:)

Ответ 3

Простой:

obj.onclick=function(e){
   if(obj.timerID){
          clearTimeout(obj.timerID);
          obj.timerID=null;
          console.log("double")
         }
       else{
          obj.timerID=setTimeout(function(){
                                            obj.timerID=null;
                                            console.log("single")
                                            },250)}
}//onclick

Ответ 4

Небольшое исправление

       if(typeof dbtimer != "undefined"){
            dbclearTimeout(timer);
            timer = undefined;
            //double click
        }else{
            dbtimer = setTimeout(function() { 
            dbtimer = undefined;
            //single click
            }, 250);
        }

Ответ 5

,   cellclick   :   
        function(){
            setTimeout(function(){
                if (this.dblclickchk) return;
                setTimeout(function(){
                    click event......                   
                },100);
            },500);
        }

,   celldblclick    :   
        function(){
            setTimeout(function(){
                this.dblclickchk    =   true;
                setTimeout(function(){
                                          dblclick event.....
                },100);
                setTimeout(function(){
                    this.dblclickchk = false;
                },3000);
            },1);
        }

Ответ 6

Я случайно обнаружил, что это работает (в случае с Bing Maps):

                 pushpin.clickTimer = -1;
                  Microsoft.Maps.Events.addHandler(pushpin, 'click', (pushpin) {
                    return function () {
                        if (pushpin.clickTimer == -1) {
                            pushpin.clickTimer = setTimeout((function (pushpin) {
                                return function () {
                                    alert('Single Clic!');
                                    pushpin.clickTimer = -1;
                                    // single click handle code here
                                }
                            }(pushpin)), 300);
                        }
                    }
                }(pushpin)));
                Microsoft.Maps.Events.addHandler(pushpin, 'dblclick', (function (pushpin) {
                    return function () {
                        alert('Double Click!');
                        clearTimeout(pushpin.clickTimer);
                        pushpin.clickTimer = -1;
                        // double click handle here
                    }
                }(pushpin)));

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