English 中文(简体)
Long Press in JavaScript?
原标题:

Is it possible to implement "long press" in JavaScript (or jQuery)? How?

alt text
(source: androinica.com)

HTML

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

JavaScript

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

There is no jQuery magic, just JavaScript timers.

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. 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:

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

You can use taphold event of jQuery mobile API.

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.

Listen for a long-press on any element:

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

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

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. I ended up using the longclick jQuery plugin (Github), which takes care of that stuff for me. If you only need to support touchscreen devices like mobile phones, you might also try the jQuery Mobile taphold event.

For modern, mobile browsers:

document.addEventListener( contextmenu , callback);

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

jQuery plugin. Just put $(expression).longClick(function() { <your code here> });. Second parameter is hold duration; default timeout is 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);
$(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):

Mouseup/down seemed to work okay on android - but not all devices ie (samsung tab4). Did not work at all on 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.

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

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. 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.

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.

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

You can use jquery-mobile s taphold. Include the jquery-mobile.js and the following code will work fine

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

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

In vanila JS if need to detect long-click after click released:

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

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]

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

You can use jquery Touch events. (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 );
  });

like this?

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




相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签