在 JavaScript 中长按?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2625210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Long Press in JavaScript?
提问by Randy Mayer
Is it possible to implement "long press" in JavaScript (or jQuery)? How?
是否可以在 JavaScript(或 jQuery)中实现“长按”?如何?

(source: androinica.com)

(来源:androinica.com)
HTML
HTML
<a href="" title="">Long press</a>
JavaScript
JavaScript
$("a").mouseup(function(){
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
return false;
});
回答by Diodeus - James MacFarlane
There is no 'jQuery' magic, just JavaScript timers.
没有“jQuery”魔法,只有 JavaScript 计时器。
var pressTimer;
$("a").mouseup(function(){
clearTimeout(pressTimer);
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
return false;
});
回答by kelunik
Based on Maycow Moura's answer, I wrote this. It also ensures that the user didn't do a right click, which would trigger a long press and works on mobile devices. DEMO
根据 Maycow Moura 的回答,我写了这个。它还确保用户没有执行右键单击,这会触发长按并在移动设备上工作。演示
var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;
var cancel = function(e) {
if (presstimer !== null) {
clearTimeout(presstimer);
presstimer = null;
}
this.classList.remove("longpress");
};
var click = function(e) {
if (presstimer !== null) {
clearTimeout(presstimer);
presstimer = null;
}
this.classList.remove("longpress");
if (longpress) {
return false;
}
alert("press");
};
var start = function(e) {
console.log(e);
if (e.type === "click" && e.button !== 0) {
return;
}
longpress = false;
this.classList.add("longpress");
if (presstimer === null) {
presstimer = setTimeout(function() {
alert("long click");
longpress = true;
}, 1000);
}
return false;
};
node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);
You should also include some indicator using CSS animations:
您还应该使用 CSS 动画包含一些指标:
p {
background: red;
padding: 100px;
}
.longpress {
-webkit-animation: 1s longpress;
animation: 1s longpress;
}
@-webkit-keyframes longpress {
0%, 20% { background: red; }
100% { background: yellow; }
}
@keyframes longpress {
0%, 20% { background: red; }
100% { background: yellow; }
}
回答by doganak
回答by ?s??o?
While it does look simple enough to implement on your own with a timeout and a couple of mouse event handlers, it gets a bit more complicated when you consider cases like click-drag-release, supporting both press and long-press on the same element, and working with touch devices like the iPad. I ended up using the longclick jQuery plugin(Github), which takes care of that stuff for me. If you only need to support touchscreen devices like mobile phones, you might also try the jQuery Mobile taphold event.
虽然它看起来很简单,可以通过超时和几个鼠标事件处理程序自行实现,但当您考虑单击-拖动-释放等情况时,它会变得有点复杂,在同一元素上同时支持按下和长按,并使用 iPad 等触控设备。我最终使用了longclick jQuery 插件( Github),它为我处理这些事情。如果你只需要支持手机等触屏设备,你也可以试试jQuery Mobile taphold event。
回答by John Doherty
I created long-press-event(0.5k pure JavaScript)to solve this, it adds a long-pressevent to the DOM.
我创建了long-press-event (0.5k 纯 JavaScript)来解决这个问题,它long-press向 DOM添加了一个事件。
Listen for a long-presson anyelement:
侦听long-press上的任何元素:
// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
console.log(e.target);
});
Listen for a long-presson a specificelement:
侦听特定元素long-press上的 a :
// get the element
var el = document.getElementById('idOfElement');
// add a long-press event listener
el.addEventListener('long-press', function(e) {
// stop the event from bubbling up
e.preventDefault()
console.log(e.target);
});
Works in IE9+, Chrome, Firefox, Safari & hybrid mobile apps (Cordova & Ionic on iOS/Android)
适用于 IE9+、Chrome、Firefox、Safari 和混合移动应用程序(iOS/Android 上的 Cordova 和 Ionic)
回答by piwko28
jQuery plugin. Just put $(expression).longClick(function() { <your code here> });. Second parameter is hold duration; default timeout is 500 ms.
jQuery 插件。就放$(expression).longClick(function() { <your code here> });。第二个参数是保持持续时间;默认超时为 500 毫秒。
(function($) {
$.fn.longClick = function(callback, timeout) {
var timer;
timeout = timeout || 500;
$(this).mousedown(function() {
timer = setTimeout(function() { callback(); }, timeout);
return false;
});
$(document).mouseup(function() {
clearTimeout(timer);
return false;
});
};
})(jQuery);
回答by tyler_mitchell
For cross platform developers (Note All answers given so far will not work on iOS):
对于跨平台开发人员(注意到目前为止给出的所有答案都不适用于 iOS):
Mouseup/down seemed to work okay on android- but not all devices ie (samsung tab4). Did not work at all on iOS.
Mouseup/down 在android上似乎工作正常- 但不是所有设备,即(三星 tab4)。在iOS上根本不起作用。
Further research its seems that this is due to the element having selection and the native magnification interupts the listener.
进一步研究似乎这是由于具有选择的元素和本地放大率中断了听者。
This event listener enables a thumbnail image to be opened in a bootstrap modal, if the user holds the image for 500ms.
如果用户将图像保留 500 毫秒,则此事件侦听器允许在引导模式中打开缩略图图像。
It uses a responsive image class therefore showing a larger version of the image. This piece of code has been fully tested upon (iPad/Tab4/TabA/Galaxy4):
它使用响应式图像类,因此显示图像的较大版本。这段代码已经在 (iPad/Tab4/TabA/Galaxy4) 上进行了全面测试:
var pressTimer;
$(".thumbnail").on('touchend', function (e) {
clearTimeout(pressTimer);
}).on('touchstart', function (e) {
var target = $(e.currentTarget);
var imagePath = target.find('img').attr('src');
var title = target.find('.myCaption:visible').first().text();
$('#dds-modal-title').text(title);
$('#dds-modal-img').attr('src', imagePath);
// Set timeout
pressTimer = window.setTimeout(function () {
$('#dds-modal').modal('show');
}, 500)
});
回答by razz
$(document).ready(function () {
var longpress = false;
$("button").on('click', function () {
(longpress) ? alert("Long Press") : alert("Short Press");
});
var startTime, endTime;
$("button").on('mousedown', function () {
startTime = new Date().getTime();
});
$("button").on('mouseup', function () {
endTime = new Date().getTime();
longpress = (endTime - startTime < 500) ? false : true;
});
});
回答by Maycow Moura
The Diodeus's answer is awesome, but it prevent you to add a onClick function, it'll never run hold function if you put an onclick. And the Razzak's answer is almost perfect, but it run hold function only on mouseup, and generally, the function runs even if user keep holding.
Diodeus 的回答很棒,但它阻止您添加 onClick 函数,如果您放置 onclick,它永远不会运行保持函数。而Razzak的回答几乎是完美的,但它只在mouseup上运行保持功能,并且通常即使用户保持保持该功能也会运行。
So, I joined both, and made this:
所以,我加入了两者,并做了这个:
$(element).on('click', function () {
if(longpress) { // if detect hold, stop onclick function
return false;
};
});
$(element).on('mousedown', function () {
longpress = false; //longpress is false initially
pressTimer = window.setTimeout(function(){
// your code here
longpress = true; //if run hold function, longpress is true
},1000)
});
$(element).on('mouseup', function () {
clearTimeout(pressTimer); //clear time on mouseup
});
回答by Kory Nunn
For modern, mobile browsers:
对于现代移动浏览器:
document.addEventListener('contextmenu', callback);
https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu
https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu

