Длительное нажатие на JavaScript?

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

alt текст 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; 
});

16 ответов


нет магии "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; 
});

основываясь на ответе 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);

вы также должны включить некоторый индикатор, используя 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; }
}

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

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

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


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

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

демо


использовать долго-пресс (0.5 k чистый JavaScript) это long-press событие для DOM.

послушать long-press on любой элемент:

// 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):

Mouseup / down, казалось, работал нормально на android - но не все устройства ie (samsung tab4). Совсем не работал на iOS.

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

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

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

ответ Diodeus является удивительным, но это мешает вам добавить функцию onClick, он никогда не будет запускать функцию hold, если вы поместите onclick. И ответ Раззака почти идеален, но он запускает функцию удержания только на 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
});

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

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

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


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

document.addEventListener('contextmenu', callback);

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


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

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

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

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

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

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


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

вы можете проверить время, чтобы определить щелчок или длительное нажатие [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);
}
} 

как это?

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