简体   繁体   中英

JavaScript: Touch Events Working on iPad but not iPhone

Is there any difference between writing JS touch events for iPad vs. iPhone? I have read a ton of documentation and as far as I can tell it should work the same way for both.

I have a drag-and-drop game, basically you grab a coin from under the dragon and drag it over to your vault. The dragging works on iPad, but not on iPhone. I'm trying to figure out why.

The game, for reference: https://codeeverydamnday.com/projects/dragondrop/dragondrop.html

The JS, abridged to just the relevant code for this question (with comments for clarity):

var dragndrop = (function() {
  var myX = "";
  var myY = "";
    // The coin's starting X and Y coordinate positions
  var coin = "";
    // The coin you start touching / dragging

  function touchStart(e) {
    e.preventDefault();
      // Prevents default behavior of scrolling when you touch/drag on mobile
    var coin = e.target;
    var touch = e.touches[0];
    var moveOffsetX = coin.offsetLeft - touch.pageX;
    var moveOffsetY = coin.offsetTop - touch.pageY;
      // Defines offset between left edge of coin and where you place your finger on it
    coin.addEventListener('touchmove', function() {
      var positionX = touch.pageX+moveOffsetX;
      var positionY = touch.pageY+moveOffsetY;
        // Defines the X-Y coordinates of wherever you stop dragging
      coin.style.left = positionX + 'px';
      coin.style.top = positionY + 'px';
        // Updates the coin's X-Y coordinates with the new positions
    }, false)
  }
  document.querySelector('body').addEventListener('touchstart', touchStart, false);
})();

If it helps, I am getting this console log error every time I click / tap on the iPad screen in the Chrome Dev Tools emulator:

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.

This error doesn't seem to prevent the dragging from working on iPad, but I'm not sure if it has anything to do with the dragging not working on mobile? I tried adding a few things to fix the error based on other Stack Overflow questions I saw (ex. adding touch-action: none; in my CSS, but the error persisted).

Anyone see anything wrong in my code? I would love to get this game playable on mobile, as that's how most people would access it!

The default value of the passive option is set to true for touch-start and touch-move events, and it being true means your function won't call preventDefault to disable scrolling.

Simply set the passive value to false to solve your issue.

 var dragndrop = (function() { var myX; var myY; var coin; function touchStart(e) { e.preventDefault(); coin = e.target; const touch = e.touches[0]; const moveOffsetX = whichArt.offsetLeft - touch.pageX; const moveOffsetY = whichArt.offsetTop - touch.pageY; coin.addEventListener("touchmove", touchMove, { passive: false }); function touchMove(e) { const touch = e.touches[0]; const positionX = touch.pageX + moveOffsetX; const positionY = touch.pageY + moveOffsetY; coin.style.left = `${positionX}px`; coin.style.top = `${positionY}px`; } } document.body.addEventListener('touchstart', touchStart, { passive: false }); })();

Edit


I looked at the code from the website you linked, and I realized that one reason the coin wasn't dragged was because of touch we were using and also because of the once option I passed to the touchmove event.

Whenever the touchmove event is used, we have to use the new touch to get the pageX and pageY positions on the screen, I decided to create a function for the touchmove event, because whenever the touchstart function is called, a new touchmove event is registered because of the anonymous function handler.

So creating and naming a function for it will prevent the same function from being added.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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