Как различить одно нажатие и событие двойного щелчка?
У меня есть одна кнопка в li с идентификатором "my_id"
. Я прикрепил два события jQuery к этому элементу
1.
$("#my_id").click(function() {
alert('single click');
});
2.
$("#my_id").dblclick(function() {
alert('double click');
});
Но каждый раз это дает мне single click
Ответы
Ответ 1
Вам нужно использовать таймаут, чтобы проверить, есть ли другой клик после первого щелчка.
Вот трюк:
// Author: Jacek Becela
// Source: http://gist.github.com/399624
// License: MIT
jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) {
return this.each(function(){
var clicks = 0, self = this;
jQuery(this).click(function(event){
clicks++;
if (clicks == 1) {
setTimeout(function(){
if(clicks == 1) {
single_click_callback.call(self, event);
} else {
double_click_callback.call(self, event);
}
clicks = 0;
}, timeout || 300);
}
});
});
}
Использование:
$("button").single_double_click(function () {
alert("Try double-clicking me!")
}, function () {
alert("Double click detected, I'm hiding")
$(this).hide()
})
<button>Click Me!</button>
EDIT:
Как указано ниже, предпочитайте использовать нативный dblclick
событие: http://www.quirksmode.org/dom/events/click.html
Или тот, который предоставляется jQuery: http://api.jquery.com/dblclick/
Ответ 2
Поведение события dblclick
объясняется в Quirksmode.
Порядок событий для a dblclick
:
- MouseDown
- MouseUp
- выберите
- MouseDown
- MouseUp
- выберите
- DblClick
Единственным исключением из этого правила является (конечно) Internet Explorer с их пользовательским порядком:
- MouseDown
- MouseUp
- выберите
- MouseUp
- DblClick
Как вы можете видеть, одновременное прослушивание обоих событий в одном элементе приведет к дополнительным вызовам вашего обработчика click
.
Ответ 3
Простая функция. Никакой jquery или другой рамки не требуется. Передавайте свои функции в качестве параметров
<div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div>
<script>
function doubleclick(el, onsingle, ondouble) {
if (el.getAttribute("data-dblclick") == null) {
el.setAttribute("data-dblclick", 1);
setTimeout(function () {
if (el.getAttribute("data-dblclick") == 1) {
onsingle();
}
el.removeAttribute("data-dblclick");
}, 300);
} else {
el.removeAttribute("data-dblclick");
ondouble();
}
}
</script>
Ответ 4
Я боюсь, что поведение зависит от браузера:
Нельзя привязывать обработчики к как события click и dblclick для тот же элемент. Последовательность события запускаются в зависимости от браузера браузеру, причем некоторые получают два нажмите события перед dblclick и другие - только один. Двойной клик чувствительность (максимальное время между клики, которые обнаруживаются как двойные клик) может варьироваться в зависимости от операционной системы и браузер, и часто настраивается пользователем.
http://api.jquery.com/dblclick/
Выполняя свой код в Firefox, alert() в обработчике click()
не позволяет вам щелкнуть второй раз. Если вы удалите такое предупреждение, вы получите оба события.
Ответ 5
Хорошо, чтобы дважды щелкнуть (дважды щелкните), вы должны сначала нажать один раз. Обработчик click()
запускается при первом щелчке, и, поскольку появляется предупреждение, у вас нет возможности сделать второй щелчок, чтобы запустить обработчик dblclick()
.
Измените обработчики, чтобы сделать что-то отличное от alert()
, и вы увидите поведение. (возможно, измените цвет фона элемента):
$("#my_id").click(function() {
$(this).css('backgroundColor', 'red')
});
$("#my_id").dblclick(function() {
$(this).css('backgroundColor', 'green')
});
Ответ 6
Вместо того, чтобы использовать больше специальных состояний и setTimeout, оказывается, что есть собственное свойство, называемое detail
, к которому вы можете получить доступ из объекта event
!
element.onclick = event => {
if (event.detail === 1) {
// it was a single click
} else if (event.detail === 2) {
// it was a double click
}
};
Современные браузеры и даже IE-9 поддерживают его :)
Источник: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
Ответ 7
Ни один из этих ответов не удовлетворил мои потребности, поэтому я создал решение, основанное на gist, отправленном @AdrienSchuler. Используйте это решение только тогда, когда вы хотите связать один клик и двойной щелчок по элементу. В противном случае я рекомендую использовать собственные click
и dblclick
прослушиватели.
Это различия:
- Vanillajs, без зависимостей
- Не ждите, когда
setTimeout
обработает обработчик click или doubleclick.
- При двойном щелчке сначала запускается обработчик кликов, затем обработчик doubleclick
JavaScript:
function makeDoubleClick(doubleClickCallback, singleClickCallback) {
var clicks = 0, timeout;
return function() {
clicks++;
if (clicks == 1) {
singleClickCallback && singleClickCallback.apply(this, arguments);
timeout = setTimeout(function() { clicks = 0; }, 400);
} else {
timeout && clearTimeout(timeout);
doubleClickCallback && doubleClickCallback.apply(this, arguments);
clicks = 0;
}
};
}
Использование:
var singleClick = function(){ console.log('single click') };
var doubleClick = function(){ console.log('double click') };
element.addEventListener('click', makeDoubleClick(doubleClick, singleClick));
Ниже приведено использование в jsfiddle, кнопка jQuery - это поведение принятого ответа.
Ответ 8
Другое простое решение Vanilla, основанное на ответе A1rPun (см. его скрипку для решения jQuery, и оба в этом).
Похоже, что для того, чтобы НЕ вызывать обработчик одного щелчка, когда пользователь дважды щелкает, обработчик одного щелчка обязательно запускается после задержки...
var single = function(e){console.log('single')},
double = function(e){console.log('double')};
var makeDoubleClick = function(e) {
var clicks = 0,
timeout;
return function (e) {
clicks++;
if (clicks == 1) {
timeout = setTimeout(function () {
single(e);
clicks = 0;
}, 250);
} else {
clearTimeout(timeout);
double(e);
clicks = 0;
}
};
}
document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false);
Ответ 9
Используйте отличный плагин jQuery Sparkle. Плагин дает вам возможность обнаруживать первый и последний клики. Вы можете использовать его для разграничения между кликом и dblclick, обнаружив, что первый щелчок был сделан за кликом.
Проверьте это на http://balupton.com/sandbox/jquery-sparkle/demo/
Ответ 10
Здесь альтернатива кода jeum для произвольного количества событий:
var multiClickHandler = function (handlers, delay) {
var clicks = 0, timeout, delay = delay || 250;
return function (e) {
clicks++;
clearTimeout(timeout);
timeout = setTimeout(function () {
if(handlers[clicks]) handlers[clicks](e);
clicks = 0;
}, delay);
};
}
cy.on('click', 'node', multiClickHandler({
1: function(e){console.log('single clicked ', e.cyTarget.id())},
2: function(e){console.log('double clicked ', e.cyTarget.id())},
3: function(e){console.log('triple clicked ', e.cyTarget.id())},
4: function(e){console.log('quadro clicked ', e.cyTarget.id())},
// ...
}, 300));
Это необходимо для cytoscape.js.
Ответ 11
Я написал простой плагин jQuery, который позволяет использовать пользовательское событие "singleclick", чтобы разделить один клик с двойным щелчком:
https://github.com/omriyariv/jquery-singleclick
$('#someDiv').on('singleclick', function(e) {
// The event will be fired with a small delay.
console.log('This is certainly a single-click');
}
Ответ 12
Как отличить одиночные клики от двойных кликов на одном и том же элементе?
Если вам не нужно смешивать их, вы можете положиться на click
и dblclick
и каждый dblclick
справится со своей задачей.
При попытке смешать их возникает проблема: событие dblclick
фактически также инициирует событие click
, поэтому вам необходимо определить, является ли одиночный щелчок "автономным" одиночным щелчком или частью двойного щелчка.
Кроме того: вы не должны использовать и click
и dblclick
для одного и того же элемента:
Нецелесообразно привязывать обработчики к событиям click и dblclick для одного и того же элемента. Последовательность запускаемых событий варьируется от браузера к браузеру, причем некоторые из них получают два события щелчка до dblclick, а другие - только одно. Чувствительность к двойному щелчку (максимальное время между щелчками, определяемое как двойной щелчок) может варьироваться в зависимости от операционной системы и браузера и часто настраивается пользователем.
Источник: https://api.jquery.com/dblclick/
Теперь о хороших новостях:
Вы можете использовать свойство detail
события, чтобы определить количество кликов, связанных с событием. Это позволяет легко обнаружить двойные щелчки внутри click
.
Проблема остается в обнаружении одиночных щелчков и в том, являются ли они частью двойного щелчка. Для этого мы вернулись к использованию таймера и setTimeout
.
Оборачивая все это вместе с использованием атрибута данных (чтобы избежать глобальной переменной) и без необходимости самостоятельно подсчитывать количество кликов, мы получаем:
HTML:
<div class="clickit" style="font-size: 200%; margin: 2em; padding: 0.25em; background: orange;">Double click me</div>
<div id="log" style="background: #efefef;"></div>
JavaScript:
<script>
var clickTimeoutID;
$( document ).ready(function() {
$( '.clickit' ).click( function( event ) {
if ( event.originalEvent.detail === 1 ) {
$( '#log' ).append( '(Event:) Single click event received.<br>' );
/** Is this a true single click or it it a single click that part of a double click?
* The only way to find out is to wait it for either a specific amount of time or the 'dblclick' event.
**/
clickTimeoutID = window.setTimeout(
function() {
$( '#log' ).append( 'USER BEHAVIOR: Single click detected.<br><br>' );
},
500 // how much time users have to perform the second click in a double click -- see accessibility note below.
);
} else if ( event.originalEvent.detail === 2 ) {
$( '#log' ).append( '(Event:) Double click event received.<br>' );
$( '#log' ).append( 'USER BEHAVIOR: Double click detected.<br>' );
window.clearTimeout( clickTimeoutID ); // it a dblclick, so cancel the single click behavior.
} // triple, quadruple, etc. clicks are ignored.
});
});
</script>
Демо-версия:
JSfiddle
Примечания о доступности и скорости двойного щелчка:
- Как говорит Википедия: "Максимальная задержка, необходимая для того, чтобы два последовательных клика интерпретировались как двойной щелчок, не стандартизирована".
- Нет способа определить скорость двойного щелчка в браузере.
- Кажется, по умолчанию 500 мс и диапазон 100-900 мм в Windows (источник)
- Подумайте о людях с ограниченными возможностями, которые в своих настройках ОС устанавливают скорость двойного щелчка до самой низкой.
- Если скорость двойного щелчка системы ниже, чем наша стандартная настройка на 500 мс выше, будут активированы оба варианта single- и двойной щелчок.
- Либо не используйте полагаться на комбинированный одиночный и двойной щелчок на одном и том же предмете.
- Или: добавьте параметр в параметры, чтобы иметь возможность увеличить значение.
Потребовалось время, чтобы найти удовлетворительное решение, надеюсь, это поможет!
Ответ 13
Мне нравится избегать jquery (и других 90-140k lib), и, как отметили браузеры, сначала обработайте onclick, так что вот что я сделал на созданном мной веб-сайте (этот пример также охватывает получение локального местоположения xy) p >
clicksNow-0; //global js, owell
function notify2(e, right) { // called from onclick= and oncontextmenu= (rc)
var x,y,xx,yy;
var ele = document.getElementById('wrap');
// offset fixed parent for local win x y
var xxx= ele.offsetLeft;
var yyy= ele.offsetTop;
//NScape
if (document.layers || document.getElementById&&!document.all) {
xx= e.pageX;
yy= e.pageY;
} else {
xx= e.clientX;
yy= e.clientY;
}
x=xx-xxx;
y=yy-yyy;
clicksNow++;
// 200 (2/10ths a sec) is about a low as i seem to be able to go
setTimeout( "processClick( " + right + " , " + x + " , " + y + ")", 200);
}
function processClick(right, x, y) {
if (clicksNow==0) return; // already processed as dblclick
if (clicksNow==2) alert('dbl');
clicksNow=0;
... handle, etc ...
}
надеюсь, что поможет
Ответ 14
это сработало для меня -
var clicked=0;
function chkBtnClcked(evnt) {
clicked++;
// wait to see if dblclick
if (clicked===1) {
setTimeout(function() {
clicked=0;
.
.
}, 300); // test for another click within 300ms
}
if (clicked===2) {
stopTimer=setInterval(function() {
clicked=0;
.
.
}, 30*1000); // refresh every 30 seconds
}
}
usage-
<div id="cloneimages" style="position: fixed;" onclick="chkBtnClcked(evnt)" title="Click for next pic; double-click for slide show"></div>
Ответ 15
Просто разместите собственный HTML-ответ на тот случай, если вам понадобится простой и HTML-код.
<p ondblclick="myFunction()" id = 'id'>Double-click me</p>
У этого, конечно, есть нативные параметры Jquery. то есть... $('#id').attr('ondblclick',function(){...})
или, как указано ранее, $('#id').dblclick(function(){...});