Один из способов сделать это - отключить pointer-events
в элементе, по которому вы щелкнули, с момента возникновения события long-press
и до следующего события mouseup
в документе.
Лучше всего, вероятно, сделать это из вашей библиотеки, так что вот ветвь этой библиотеки, которая теперь предоставляет метод preventDefaultClick()
для CustomEvent:
(function (window, document) {
'use strict';
var timer = null;
// check if we're using a touch screen
var isTouch = (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0));
// switch to touch events if using a touch screen
var mouseDown = isTouch ? 'touchstart' : 'mousedown';
var mouseOut = isTouch ? 'touchcancel' : 'mouseout';
var mouseUp = isTouch ? 'touchend' : 'mouseup';
var mouseMove = isTouch ? 'touchmove' : 'mousemove';
// wheel/scroll events
var mouseWheel = 'mousewheel';
var wheel = 'wheel';
var scrollEvent = 'scroll';
// patch CustomEvent to allow constructor creation (IE/Chrome)
if (typeof window.CustomEvent !== 'function') {
window.CustomEvent = function(event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
};
window.CustomEvent.prototype = window.Event.prototype;
}
// listen to mousedown event on any child element of the body
document.addEventListener(mouseDown, function(e) {
var el = e.target;
// get delay from html attribute if it exists, otherwise default to 1500
var longPressDelayInMs = parseInt(el.getAttribute('data-long-press-delay') || '1500', 10);
// start the timer
timer = setTimeout(fireLongPressEvent.bind(el, e), longPressDelayInMs);
});
// clear the timeout if the user releases the mouse/touch
document.addEventListener(mouseUp, function() {
clearTimeout(timer);
});
// clear the timeout if the user leaves the element
document.addEventListener(mouseOut, function() {
clearTimeout(timer);
});
// clear if the mouse moves
document.addEventListener(mouseMove, function() {
clearTimeout(timer);
});
// clear if the Wheel event is fired in the element
document.addEventListener(mouseWheel, function() {
clearTimeout(timer);
});
// clear if the Scroll event is fired in the element
document.addEventListener(wheel, function() {
clearTimeout(timer);
});
// clear if the Scroll event is fired in the element
document.addEventListener(scrollEvent, function() {
clearTimeout(timer);
});
/**
* Fires the 'long-press' event on element
* @returns {void}
*/
function fireLongPressEvent() {
var evt = new CustomEvent('long-press', { bubbles: true, cancelable: true });
// Expose a method to prevent the incoming click event
var el = this;
evt.preventDefaultClick = function() {
// disable all pointer-events
el.style["pointer-events"] = "none";
// reenable at next mouseUp
document.addEventListener(mouseUp, e => {
el.style["pointer-events"] = "all";
}, {once: true});
};
// fire the long-press event
this.dispatchEvent(evt);
clearTimeout(timer);
}
}(window, document));
btn.addEventListener('click', e => console.log('clicked'));
btn.addEventListener('long-press', e => {
console.log('long-press');
e.preventDefaultClick(); // prevents the incoming 'click' event
});
<button data-long-press-delay="500" id="btn">click me</button>
Но если, как и у меня, у вас есть мышь, которая запускает кучу событий при каждом пролистывании, то вы можете предпочесть это демо, где есть триггеры тайм-аута колеса и т. Д.был отключен:
(function (window, document) {
'use strict';
var timer = null;
// check if we're using a touch screen
var isTouch = (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0));
// switch to touch events if using a touch screen
var mouseDown = isTouch ? 'touchstart' : 'mousedown';
var mouseOut = isTouch ? 'touchcancel' : 'mouseout';
var mouseUp = isTouch ? 'touchend' : 'mouseup';
var mouseMove = isTouch ? 'touchmove' : 'mousemove';
// wheel/scroll events
var mouseWheel = 'mousewheel';
var wheel = 'wheel';
var scrollEvent = 'scroll';
// patch CustomEvent to allow constructor creation (IE/Chrome)
if (typeof window.CustomEvent !== 'function') {
window.CustomEvent = function(event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
};
window.CustomEvent.prototype = window.Event.prototype;
}
// listen to mousedown event on any child element of the body
document.addEventListener(mouseDown, function(e) {
var el = e.target;
// get delay from html attribute if it exists, otherwise default to 1500
var longPressDelayInMs = parseInt(el.getAttribute('data-long-press-delay') || '1500', 10);
// start the timer
timer = setTimeout(fireLongPressEvent.bind(el, e), longPressDelayInMs);
});
// clear the timeout if the user releases the mouse/touch
document.addEventListener(mouseUp, function() {
clearTimeout(timer);
});
// clear the timeout if the user leaves the element
document.addEventListener(mouseOut, function() {
clearTimeout(timer);
});
// clear if the mouse moves
document.addEventListener(mouseMove, function() {
// clearTimeout(timer);
});
// clear if the Wheel event is fired in the element
document.addEventListener(mouseWheel, function() {
// clearTimeout(timer);
});
// clear if the Scroll event is fired in the element
document.addEventListener(wheel, function() {
// clearTimeout(timer);
});
// clear if the Scroll event is fired in the element
document.addEventListener(scrollEvent, function() {
// clearTimeout(timer);
});
/**
* Fires the 'long-press' event on element
* @returns {void}
*/
function fireLongPressEvent() {
var evt = new CustomEvent('long-press', { bubbles: true, cancelable: true });
// Expose a method to prevent the incoming click event
var el = this;
evt.preventDefaultClick = function() {
// disable all pointer-events
el.style["pointer-events"] = "none";
// reenable at next mouseUp
document.addEventListener(mouseUp, e => {
el.style["pointer-events"] = "all";
}, {once: true});
};
// fire the long-press event
this.dispatchEvent(evt);
clearTimeout(timer);
}
}(window, document));
btn.addEventListener('click', e => console.log('clicked'));
btn.addEventListener('long-press', e => {
console.log('long-press');
e.preventDefaultClick(); // prevents the incoming 'click' event
});
<button data-long-press-delay="500" id="btn">click me</button>