简体   繁体   English

在 JavaScript 中长按?

[英]Long Press in JavaScript?

Is it possible to implement "long press" in JavaScript (or jQuery)?是否可以在 JavaScript(或 jQuery)中实现“长按”? How?如何?

替代文字
(source: androinica.com ) (来源: androinica.com

HTML HTML

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

JavaScript JavaScript

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

There is no 'jQuery' magic, just JavaScript timers.没有“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; 
});

Based on Maycow Moura's answer, I wrote this.根据 Maycow Moura 的回答,我写了这个。 It also ensures that the user didn't do a right click, which would trigger a long press and works on mobile devices.它还确保用户没有执行右键单击,这会触发长按并在移动设备上工作。 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);

You should also include some indicator using CSS 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; }
}

您可以使用 jQuery 移动 API 的taphold事件。

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

I created long-press-event (0.5k pure JS) to solve this, it adds a long-press event to the DOM.我创建了long-press-event (0.5k pure JS)来解决这个问题,它向 DOM 添加了一个long-press事件。

Listen for a long-press on any element:long-press任何元素:

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

Listen for a long-press on a specific element: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);
});

Works in IE9+, Chrome, Firefox, Safari & hybrid mobile apps (Cordova & Ionic on iOS/Android)适用于 IE9+、Chrome、Firefox、Safari 和混合移动应用程序(iOS/Android 上的 Cordova 和 Ionic)

Demo演示

While it does look simple enough to implement on your own with a timeout and a couple of mouse event handlers, it gets a bit more complicated when you consider cases like click-drag-release, supporting both press and long-press on the same element, and working with touch devices like the iPad.虽然它看起来很简单,可以通过超时和几个鼠标事件处理程序自行实现,但当您考虑单击-拖动-释放等情况时,它会变得有点复杂,在同一元素上同时支持按下和长按,并使用 iPad 等触控设备。 I ended up using the longclick jQuery plugin ( Github ), which takes care of that stuff for me.我最终使用了longclick jQuery 插件( Github ),它为我处理这些事情。 If you only need to support touchscreen devices like mobile phones, you might also try the jQuery Mobile taphold event .如果你只需要支持手机等触屏设备,你也可以试试jQuery Mobile taphold event

jQuery plugin. jQuery 插件。 Just put $(expression).longClick(function() { <your code here> });只需输入$(expression).longClick(function() { <your code here> }); . . Second parameter is hold duration;第二个参数是保持持续时间; default timeout is 500 ms.默认超时为 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);

For modern, mobile browsers:对于现代移动浏览器:

document.addEventListener('contextmenu', callback);

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

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

For cross platform developers (Note All answers given so far will not work on iOS) :对于跨平台开发人员(注意到目前为止给出的所有答案都不适用于 iOS)

Mouseup/down seemed to work okay on android - but not all devices ie (samsung tab4). Mouseup/down 在android上似乎工作正常 - 但不是所有设备,即(三星 tab4)。 Did not work at all on iOS .iOS上根本不起作用。

Further research its seems that this is due to the element having selection and the native magnification interupts the listener.进一步研究似乎这是由于具有选择的元素和本地放大率中断了听者。

This event listener enables a thumbnail image to be opened in a bootstrap modal, if the user holds the image for 500ms.如果用户将图像保留 500 毫秒,则此事件侦听器允许在引导模式中打开缩略图图像。

It uses a responsive image class therefore showing a larger version of the image.它使用响应式图像类,因此显示图像的较大版本。 This piece of code has been fully tested upon (iPad/Tab4/TabA/Galaxy4):这段代码已经在 (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)
});

The Diodeus's answer is awesome, but it prevent you to add a onClick function, it'll never run hold function if you put an onclick. Diodeus 的回答很棒,但它阻止您添加 onClick 函数,如果您放置 onclick,它永远不会运行保持函数。 And the Razzak's answer is almost perfect, but it run hold function only on mouseup, and generally, the function runs even if user keep holding.而Razzak的回答几乎是完美的,但它只在mouseup上运行保持功能,并且通常即使用户保持保持该功能也会运行。

So, I joined both, and made this:所以,我加入了两者,并做到了这一点:

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

You could set the timeout for that element on mouse down and clear it on mouse up:您可以在鼠标按下时设置该元素的超时并在鼠标抬起时清除它:

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

With this each element gets its own timeout.有了这个,每个元素都有自己的超时。

You can use jquery-mobile's taphold.您可以使用 jquery-mobile 的 taphold。 Include the jquery-mobile.js and the following code will work fine包括 jquery-mobile.js 和以下代码将正常工作

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

Most elegant and clean is a jQuery plugin: https://github.com/untill/jquery.longclick/ , also available as packacke: https://www.npmjs.com/package/jquery.longclick .最优雅和干净的是一个 jQuery 插件: https : //github.com/untill/jquery.longclick/ ,也可以作为 Packacke 使用: https ://www.npmjs.com/package/jquery.longclick。

In short, you use it like so:简而言之,您可以像这样使用它:

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

The advantage of this plugin is that, in contrast to some of the other answers here, click events are still possible.这个插件的优点是,与这里的其他一些答案相比,点击事件仍然是可能的。 Note also that a long click occurs, just like a long tap on a device, before mouseup.另请注意,在鼠标悬停之前,会发生长按,就像在设备上长按一样。 So, that's a feature.所以,这是一个特点。

I needed something for longpress keyboard events, so I wrote this.我需要长按键盘事件的东西,所以我写了这个。

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

This worked for me:这对我有用:

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

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

https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/oncontextmenu https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/oncontextmenu

In vanila JS if need to detect long-click after click released:在 vanila 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 !!!");
        }
      }
    }

May need to use timer if need to check long-click while clicking.如果需要在单击时检查长按,可能需要使用计时器。 But for most case after release click is enought.但对于大多数情况,发布后点击就足够了。

For me it's work with that code (with jQuery):对我来说,它适用于该代码(使用 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);

You can check the time to identify Click or Long Press [jQuery]可以通过查看时间来识别 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);
}
} 

like this?像这样?

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

You can use jquery Touch events.您可以使用jquery触摸事件。 ( see here ) 见这里

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM