Долгое нажатие в JavaScript? - PullRequest
109 голосов
/ 13 апреля 2010

Возможно ли реализовать "длинное нажатие" в JavaScript (или jQuery)? Как?

альтернативный текст 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; 
});

Ответы [ 18 ]

155 голосов
/ 13 апреля 2010

Нет волшебства 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; 
});
28 голосов
/ 11 декабря 2014

Основываясь на ответе Мейков Мора, я написал это. Это также гарантирует, что пользователь не сделал щелчок правой кнопкой мыши, который вызовет долгое нажатие и работает на мобильных устройствах. 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);

Вы должны также включить некоторые индикаторы, использующие 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; }
}
25 голосов
/ 13 сентября 2011

Вы можете использовать taphold событие мобильного API jQuery.

jQuery("a").on("taphold", function( event ) { ... } )
15 голосов
/ 24 февраля 2011

Хотя это выглядит достаточно просто для самостоятельной реализации с тайм-аутом и парой обработчиков событий мыши, все становится немного сложнее, когда вы рассматриваете такие случаи, как нажатие-перетаскивание-отпускание, поддерживая нажатие и длительное нажатие тот же элемент, и работа с сенсорными устройствами, такими как iPad. В итоге я использовал плагин longclick jQuery ( Github ), который позаботился обо мне. Если вам нужна только поддержка устройств с сенсорным экраном, таких как мобильные телефоны, вы можете также попробовать событие jQuery Mobile * - 1006 *.

10 голосов
/ 01 октября 2012

плагин 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);
8 голосов
/ 09 июня 2017

Я создал long-press-event (0.5k чистый JavaScript) , чтобы решить эту проблему, он добавляет событие long-press в DOM.

Прослушайте 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 и гибридных мобильных приложениях (Cordova & Ionic для iOS / Android)

Демо

5 голосов
/ 23 октября 2015

Для кроссплатформенных разработчиков (Примечание. Все приведенные ответы не будут работать на iOS) :

Mouseup / down вроде бы работает нормально на android - но не на всех устройствах т.е. (samsung tab4). Не работал вообще на iOS .

Дальнейшие исследования показывают, что это связано с тем, что элемент выделен, а собственное увеличение прерывает слушателя.

Этот прослушиватель событий позволяет открывать уменьшенное изображение в режиме начальной загрузки, если пользователь удерживает изображение в течение 500 мс.

Он использует класс адаптивного изображения, поэтому показывает увеличенную версию изображения. Этот фрагмент кода был полностью протестирован (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)
});
5 голосов
/ 26 марта 2013
$(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;
    });
});

DEMO

4 голосов
/ 20 апреля 2014

Ответ от Diodeus потрясающий, но он не позволяет добавить функцию onClick, он никогда не запустит функцию удержания, если вы нажмете кнопку onclick. И ответ Раззака почти идеален, но он запускает функцию удержания только при наведении мыши, и, как правило, эта функция запускается, даже если пользователь продолжает удерживать.

Итак, я присоединился к обоим, и сделал это:

$(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
});
2 голосов
/ 12 мая 2015

Для современных мобильных браузеров:

document.addEventListener('contextmenu', callback);

https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu

...