JavaScript 中的长按?

是否有可能在 JavaScript (或 jQuery)中实现“长按”? 如何实现?

alt text
(来源: Androinica.com)

超文本标示语言

<a href="" title="">Long press</a>

JavaScript

$("a").mouseup(function(){
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
return false;
});
217638 次浏览

没有“ 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;
});

你可以在鼠标上设置该元素的超时时间,然后在鼠标上清除它:

$("a").mousedown(function() {
// set timeout for this element
var timeout = window.setTimeout(function() { /* … */ }, 1234);
$(this).mouseup(function() {
// clear timeout for this element
window.clearTimeout(timeout);
// reset mouse up event handler
$(this).unbind("mouseup");
return false;
});
return false;
});

这样,每个元素都有自己的超时时间。

虽然它看起来足够简单,只需要一个超时和几个鼠标事件处理程序就可以实现,但是当你考虑到诸如点击-拖动-释放、支持同一元素上的按压和长按、以及使用像 iPad 这样的触摸设备时,它就变得有点复杂了。我最终使用的 Longclick jQuery 插件(Github) ,它为我照顾的东西。如果你只需要支持像手机这样的触摸屏设备,你也可以试试 移动隐藏事件

您可以使用 jQuery 移动 API 的 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳事件。

jQuery("a").on("taphold", function( event ) { ... } )

对我来说,这就是使用代码(使用 jQuery)的工作:

var int       = null,
fired     = false;


var longclickFilm = function($t) {
$body.css('background', 'red');
},
clickFilm = function($t) {
$t  = $t.clone(false, false);
var $to = $('footer > div:first');
$to.find('.empty').remove();
$t.appendTo($to);
},
touchStartFilm = function(event) {
event.preventDefault();
fired     = false;
int       = setTimeout(function($t) {
longclickFilm($t);
fired = true;
}, 2000, $(this)); // 2 sec for long click ?
return false;
},
touchEndFilm = function(event) {
event.preventDefault();
clearTimeout(int);
if (fired) return false;
else  clickFilm($(this));
return false;
};


$('ul#thelist .thumbBox')
.live('mousedown touchstart', touchStartFilm)
.live('mouseup touchend touchcancel', touchEndFilm);

您可以检查标识 Click 或 Long Press 的时间[ jQuery ]

function AddButtonEventListener() {
try {
var mousedowntime;
var presstime;
$("button[id$='" + buttonID + "']").mousedown(function() {
var d = new Date();
mousedowntime = d.getTime();
});
$("button[id$='" + buttonID + "']").mouseup(function() {
var d = new Date();
presstime = d.getTime() - mousedowntime;
if (presstime > 999/*You can decide the time*/) {
//Do_Action_Long_Press_Event();
}
else {
//Do_Action_Click_Event();
}
});
}
catch (err) {
alert(err.message);
}
}

第二个参数是保持时间,默认超时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);
$(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;
});
});

演示

Diodeus 的回答很棒,但是它阻止你添加 onClick 函数,如果你添加 onClick,它永远不会运行 hold 函数。Razzak 的回答几乎是完美的,但它只在鼠标上运行 hold 函数,而且一般来说,即使用户保持 hold,函数也会运行。

所以我两个都加入了,做了这个:

$(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
});

基于梅科 · 莫拉的回答,我写了这个。它还确保用户不会右键单击,这将触发一个长按,并在移动设备上工作。演示

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);

您还应该包括一些指示器使用 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; }
}

您可以使用 jquery-mobile 的 taphold

$(document).on("pagecreate","#pagename",function(){
$("p").on("taphold",function(){
$(this).hide(); //your code
});
});

对于现代的移动浏览器来说:

document.addEventListener('contextmenu', callback);

Https://developer.mozilla.org/en-us/docs/web/events/contextmenu

对于跨平台开发人员 (注意到目前为止给出的所有答案都不能在 iOS 上运行):

Mouseup/down 似乎在 机器人上运行良好——但并非所有设备(三星 tab4)。在 IOS上完全不起作用。

进一步的研究表明,这似乎是由于元素的选择和本土放大打断了听者。

此事件侦听器允许在引导模式下打开一个缩略图,如果用户持有该图像500ms。

它使用了一个响应图像类,因此显示了图像的一个更大的版本。 这段代码已经在 iPad/Tab4/TabA/Galaxy 4上进行了全面测试:

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)
});

像这样?

target.addEeventListener("touchstart", function(){
// your code ...
}, false);

为了解决这个问题,我创建了 长时间新闻发布会 (0.5 k 纯 JS),它向 DOM 添加了一个 long-press事件。

侦听 任何元素上的 long-press:

// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
console.log(e.target);
});

侦听 具体点元素上的 long-press:

// 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);
});

适用于 IE9 + ,Chrome,Firefox,Safari 和混合移动应用程序(iOS/Android 上的 Cordova 和 Ionic)

演示

你可以使用 jquery触摸事件。(看这里)

  let holdBtn = $('#holdBtn')
let holdDuration = 1000
let holdTimer


holdBtn.on('touchend', function () {
// finish hold
});
holdBtn.on('touchstart', function () {
// start hold
holdTimer = setTimeout(function() {
//action after certain time of hold
}, holdDuration );
});

我需要一些用于长按键盘事件的东西,所以我写了这个。

var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;


document.addEventListener('keydown', function(e) {
if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
longpressFunc = setTimeout(function() {
console.log('longpress triggered');
longpressActive = true;
}, longpressTimeout);


// any key not defined as a longpress
} else if (longpressKeys.indexOf(e.keyCode) == -1) {
console.log('shortpress triggered');
}
});


document.addEventListener('keyup', function(e) {
clearTimeout(longpressFunc);
longpressFunc = null;


// longpress key triggered as a shortpress
if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
console.log('shortpress triggered');
}
longpressActive = false;
});

这对我很有效:

const a = document.querySelector('a');


a.oncontextmenu = function() {
console.log('south north');
};

Https://developer.mozilla.org/docs/web/api/globaleventhandlers/oncontextmenu

在香草 JS 如果需要检测长点击后发布的点击:

    document.addEventListener("mousedown", longClickHandler, true);
document.addEventListener("mouseup", longClickHandler, true);


let startClick = 0;
function longClickHandler(e){
if(e.type == "mousedown"){
startClick = e.timeStamp;
}
else if(e.type == "mouseup" && startClick > 0){
if(e.timeStamp - startClick > 500){  // 0.5 secound
console.log("Long click !!!");
}
}
}

可能需要使用计时器,如果需要检查长点击时点击。但是对于大多数情况下发布后点击就足够了。