Est-il possible d'implémenter "long press" en JavaScript (ou jQuery)? Comment?
alt text http://androinica.com/wp-content/uploads/2009/11/longpress_options.png
HTML
<a href="" title="">Long press</a>
JavaScript
$("a").mouseup(function(){
// Clear timeout
return false;
}).mousedown(function(){
// Set timeout
return false;
});
Il n'y a pas de magie 'jQuery', juste des minuteries 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;
});
Basé sur la réponse de Maycow Moura, j'ai écrit ceci. Cela garantit également que l'utilisateur ne fait pas un clic droit, ce qui déclencherait une pression longue et fonctionnerait sur les appareils mobiles. DEMO
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);
Vous devez également inclure des indicateurs utilisant des 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; }
}
Vous pouvez utiliser l'événement taphold de l'API mobile jQuery.
jQuery("a").on("taphold", function( event ) { ... } )
Même si cela semble assez simple à implémenter vous-même avec un délai d’expiration et quelques gestionnaires d’événements de souris, cela devient un peu plus compliqué lorsque vous considérez des cas comme clic-glisser-relâcher, prenant en charge à la fois l’appui et la pression longue sur le même élément et travailler avec des appareils tactiles comme l'iPad. J'ai fini par utiliser le plugin longclick jQuery ( Github ), qui s'occupe de ce travail pour moi. Si vous devez uniquement prendre en charge des périphériques à écran tactile tels que les téléphones mobiles, vous pouvez également essayer l’événement taphold jQuery Mobile .
plugin jQuery. Il suffit de mettre $(expression).longClick(function() { <your code here> });
. Le deuxième paramètre est la durée de maintien; le délai d'attente par défaut est de 500 ms.
(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);
J'ai créé long-press-event(0.5k JavaScript pur)} pour résoudre ce problème, il ajoute un événement long-press
au DOM.
Écoutez l'élément long-press
sur any:
// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
console.log(e.target);
});
Écoutez un long-press
sur un élément spécifique:
// 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);
});
Fonctionne dans les applications mobiles IE9 +, Chrome, Firefox, Safari et hybrides (Cordova et Ionic sur iOS/Android))
$(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;
});
});
La réponse de Diodeus est géniale, mais cela vous empêche d'ajouter une fonction onClick, elle ne fonctionnera jamais si vous mettez un onclick. Et la réponse du Razzak est presque parfaite, mais elle ne fonctionne que sur la souris et généralement, la fonction est exécutée même si l’utilisateur continue de tenir.
Donc, j'ai rejoint les deux, et fait ceci:
$(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
});
Pour les développeurs multiplateformes (Remarque Toutes les réponses données jusqu'à présent ne fonctionneront pas sur iOS) :
Mouseup/down semblait fonctionner correctement sur Android - mais pas sur tous les appareils, par exemple (Samsung Tab4). Ne fonctionnait pas du tout sur iOS .
Des recherches plus poussées semblent indiquer que cela est dû au fait que l'élément est sélectionné et que le grossissement natif interrompt l'auditeur.
Cet écouteur d'événements permet d'ouvrir une image miniature dans un mode de démarrage, si l'utilisateur détient l'image pendant 500 ms.
Il utilise une classe d'image réactive affichant donc une version plus grande de l'image ..__ Ce code a été entièrement testé sur (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)
});
Pour les navigateurs mobiles modernes:
document.addEventListener('contextmenu', callback);
https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu
Vous pouvez définir le délai d'expiration de cet élément lorsque la souris est enfoncée et l'effacer lorsque cette dernière est activée:
$("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;
});
Avec cela, chaque élément obtient son propre délai d'attente.
Le plus élégant et le plus propre est un plugin jQuery: https://github.com/untill/jquery.longclick/ , Également disponible en packacke: https: // www. npmjs.com/package/jquery.longclick .
En bref, vous l'utilisez comme ceci:
$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );
L'avantage de ce plugin est que, contrairement à certaines des autres réponses ici, les événements de clic sont toujours possibles. Notez également qu'un clic long se produit, tout comme un clic long sur un périphérique, avant mouseup. Donc, c'est une fonctionnalité.
Vous pouvez utiliser le taphold de jquery-mobile. Incluez le fichier jquery-mobile.js et le code suivant fonctionnera correctement
$(document).on("pagecreate","#pagename",function(){
$("p").on("taphold",function(){
$(this).hide(); //your code
});
});
Vous pouvez vérifier le temps d'identifier Click ou appuyez longuement sur [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);
}
}
Vous pouvez utiliser les événements jquery
Touch. ( vois ici )
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 );
});
Pour moi, c'est travailler avec ce code (avec 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);
J'avais besoin de quelque chose pour les événements de clavier longue presse, alors j'ai écrit ceci.
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;
});
comme ça?
doc.addEeventListener("touchstart", function(){
// your code ...
}, false);