Долгое нажатие в JavaScript?

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

alt text
(источник: androinica.com)

HTML

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

JavaScript

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

Ответ 1

Магии "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; 
});

Ответ 2

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

Ответ 3

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

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

Ответ 4

Хотя он выглядит достаточно простым, чтобы реализовать самостоятельно с тайм-аутом и несколькими обработчиками событий мыши, он становится немного более сложным, когда вы рассматриваете такие случаи, как click-drag-release, поддерживая как прессу, так и долгое нажатие на тот же элемент и работает с сенсорными устройствами, такими как iPad. Я закончил использовать плагин longclick jQuery (Github), который позаботится об этом для меня, Если вам нужно только поддерживать сенсорные устройства, такие как мобильные телефоны, вы также можете попробовать событие jQuery Mobile taphold.

Ответ 5

Плагин 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);

Ответ 6

Я создал 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)

демонстрация

Ответ 7

$(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

Ответ 8

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

Mouseup/down, похоже, хорошо работает на андроиде, но не на всех устройствах, т.е. (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)
});

Ответ 9

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

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

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

Ответ 10

Вы можете установить тайм-аут для этого элемента на мыши вниз и очистить его с помощью мыши вверх:

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

При этом каждый элемент получает свой собственный тайм-аут.

Ответ 12

Вы можете использовать jquery-mobile taphold. Включите jquery-mobile.js, и следующий код будет работать нормально

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

Ответ 13

Самый элегантный и чистый плагин jQuery: https://github.com/untill/jquery.longclick/, также доступны как packacke: https://www.npmjs.com/package/jquery.longclick.

Короче говоря, вы используете его так:

$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );

Преимущество этого плагина в том, что, в отличие от некоторых других ответов здесь, события click по-прежнему возможны. Обратите также внимание на то, что длинный щелчок происходит, как и длинный щелчок на устройстве, перед нажатием мыши. Итак, эта функция.

Ответ 14

Для меня это работает с этим кодом (с 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);

Ответ 15

Вы можете проверить время идентификации 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);
}
} 

Ответ 16

как это?

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

Ответ 17

Вы можете использовать jquery Touch событий. (см. здесь)

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

Ответ 18

Мне нужно что-то для длинных нажатий клавиатуры, поэтому я написал это.

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