13

I have a button which is supposed to trigger a custom behaviour. Therefore I am using Jquery's contextmenu event. Please see my fiddle.

Currently I am binding the event this way:

$( "#mybutton" ).contextmenu(function() {
  alert( "Handler for .contextmenu() called." );
});

I also tried to bind it like this:

$( "#mybutton" ).on('contextmenu', function() {
  alert( "Handler for .contextmenu() called." );
});

As you will see in my fiddle I disabled the default ios behaviour for longpress by using:

body { -webkit-touch-callout: none !important; }
input { -webkit-user-select: none !important; }

I tested my fiddle in:

  • Chrome, latest version on windows (using right-click and touch)
  • Chrome on Android using taphold
  • Internet Explorer, latest version on windows (using right-click and touch)
  • Opera, latest version on windows (using right-click and touch)
  • Firefox, latest version on windows (using right-click and touch)
  • Safari, on macOS Sierra, (using right-click)

All of the above work as expected. Unfortunately, this does not work on ios/Safari on my Ipad. The current Safari version is 10.1.2

I tried to debug this by connecting the Ipad to my mac and logging console output. It seems the event is never fired.

I already looked for solutions but unfortunately, the only solutions seem to be either using jquery-mobile's taphold which I want to avoid or writing a custom timer-based event handlers which is also not a very clean solution, imho.

Has anyone had a similar experience and maybe found a solution?

Sibiraj
  • 4,486
  • 7
  • 33
  • 57
indexoutofbounds
  • 793
  • 12
  • 32

2 Answers2

0

I have tried some behaviours and it is a little extrange, I can't give you a exact answer, try this code maybe

But, in my experience, IOS and Safari always do these kind of things just to keep good user experience, and I would suggest to you, to not rely on context menu (at least in mobile devices), instead of that, use a dedicate button to open html generated menus, like the tipical three dots button, it is a matter of user experience.

Good luck.

$( "#mybutton" ).contextmenu(function(event) {
  event.preventDefault();
  console.log("asdf");
});
.mystyle{
  width: 450px;
  height: 450px;
}
<input class="mystyle" id="mybutton" type="button" value="button">
0

This project works here: https://github.com/john-doherty/long-press-event

For example:

<html>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <script>
/*!
 * long-press-event - v2.2.0
 * Pure JavaScript long-press-event
 * https://github.com/john-doherty/long-press-event
 * @author John Doherty <www.johndoherty.info>
 * @license MIT
 */
!function(e,t){"use strict";var n=null,a="ontouchstart"in e||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints>0,i=a?"touchstart":"mousedown",o=a?"touchend":"mouseup",m=a?"touchmove":"mousemove",u=0,r=0,s=10,c=10;function l(i){v(i);var m=i.target,u=parseInt(m.getAttribute("data-long-press-delay")||"500",10);n=function(t,n){if(!(e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame&&e.mozCancelRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame))return e.setTimeout(t,n);var a=(new Date).getTime(),i={},o=function(){(new Date).getTime()-a>=n?t.call():i.value=requestAnimFrame(o)};return i.value=requestAnimFrame(o),i}(function(e){v();var n=a?e.touches[0].clientX:e.clientX,i=a?e.touches[0].clientY:e.clientY;this.dispatchEvent(new CustomEvent("long-press",{bubbles:!0,cancelable:!0,detail:{clientX:n,clientY:i}}))&&t.addEventListener(o,function e(n){t.removeEventListener(o,e,!0),function(e){e.stopImmediatePropagation(),e.preventDefault(),e.stopPropagation()}(n)},!0)}.bind(m,i),u)}function v(t){var a;(a=n)&&(e.cancelAnimationFrame?e.cancelAnimationFrame(a.value):e.webkitCancelAnimationFrame?e.webkitCancelAnimationFrame(a.value):e.webkitCancelRequestAnimationFrame?e.webkitCancelRequestAnimationFrame(a.value):e.mozCancelRequestAnimationFrame?e.mozCancelRequestAnimationFrame(a.value):e.oCancelRequestAnimationFrame?e.oCancelRequestAnimationFrame(a.value):e.msCancelRequestAnimationFrame?e.msCancelRequestAnimationFrame(a.value):clearTimeout(a)),n=null}"function"!=typeof e.CustomEvent&&(e.CustomEvent=function(e,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var a=t.createEvent("CustomEvent");return a.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),a},e.CustomEvent.prototype=e.Event.prototype),e.requestAnimFrame=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t){e.setTimeout(t,1e3/60)},t.addEventListener(o,v,!0),t.addEventListener(m,function(e){var t=Math.abs(u-e.clientX),n=Math.abs(r-e.clientY);(t>=s||n>=c)&&v()},!0),t.addEventListener("wheel",v,!0),t.addEventListener("scroll",v,!0),t.addEventListener(i,function(e){u=e.clientX,r=e.clientY,l(e)},!0)}(window,document);

// listen for long-press events
document.addEventListener('long-press', function(e) {
  e.target.setAttribute('data-editing', 'true');
});

  </script>
  <style>
.dock-item {
  font-size: 14px;
  font-family: arial;
  display: inline-block;
  margin: 10px;
  padding: 10px;
  border: 1px solid #ccc;
  cursor: pointer;
  width: 70px;
  height: 70px;
  border-radius: 3px;
  text-align: center;
  user-select: none;
}

.no-text-select {
  -webkit-touch-callout:none; /* iOS Safari */
  -webkit-user-select:none;   /* Chrome/Safari/Opera */
  -khtml-user-select:none;    /* Konqueror */
  -moz-user-select:none;      /* Firefox */
  -ms-user-select:none;       /* Internet Explorer/Edge */
  user-select:none;           /* Non-prefixed version */
  -webkit-tap-highlight-color:rgba(0,0,0,0);
}

@keyframes jiggle {
  0% {
    transform: rotate(-1deg);
  }
  50% {
    transform: rotate(1deg);
  }
}

.dock-item[data-editing="true"] {
  animation: jiggle 0.2s infinite;
  border: 1px solid #aaa;
  box-shadow: 0 0 1px rgba(0,0,0,.85);
}
  </style>
  <body>
    <div class="no-text-select dock-item" data-long-press-delay="700">Press and hold me for 0.750s</div>
    <div class="no-text-select dock-item">Press and hold me for 0.5s</div>
  </body>
</html>
Jared Updike
  • 7,165
  • 8
  • 46
  • 72