Asperger
Asperger

Reputation: 3222

Touchend doesnt work, even after calling e.preventDefault()

Ok I am in a big predicament.

I stumbled across the touchend bug. After touchmove the touchend event doesnt work, no matter what I do.

I tried adding preventDefault() within touchmove. I also tried to replace touchend with touchcancel. It all fails. I did that read that this is related to scrolling in touch enabled devices but I didnt find any working solution so far.

I know this could be solved with JQuery but I prefer doing this the Vanilla JS way so that I can learn whats going on under the hood.

var touchActive = false;

elem.addEventListener("touchstart", function (event) {
    touchActive = true;
});
elem.addEventListener("touchend", function (event) {
    touchActive = false;
});
elem.addEventListener("touchmove", function (event) {
    if(touchActive){
    }
    else{
    }
});

So why doesnt touchend work?

Upvotes: 0

Views: 4656

Answers (2)

Asperger
Asperger

Reputation: 3222

If you are using Android < 6.0 then you will be forced to use both touchstart and touchmove events or ending events wont be possible unless you are thinking of integrating preventDefault. The latter might affect your scrolling so here is my solution:

https://jsfiddle.net/z9p7uxp2/

var x = document.getElementsByTagName('div')[0];

document.getElementsByTagName('div')[0].addEventListener("touchend", function (event) {
    x.style.background = "black"
});
document.getElementsByTagName('div')[0].addEventListener("touchcancel", function (event) {
    x.style.background = "black"
});
document.getElementsByTagName('div')[0].addEventListener("touchmove", function (event) {
    x.style.background = "red"
});

Upvotes: 1

cynicaljoy
cynicaljoy

Reputation: 2087

I tried to recreate your scenario with the following:

<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
        <style type="text/css">
        #foobar {
            width: 200px;
            height: 200px;
            background-color: red;
            margin: 0 auto;
        }
        </style>
    </head>
    <body>
        <div id="foobar"></div>
        <script type="text/javascript">
        var touchActive = false;

        var elem = document.getElementById("foobar")

        elem.addEventListener("touchstart", function (event) {
            console.log("Touch Start");
            touchActive = true;
        });
        elem.addEventListener("touchend", function (event) {
            console.log("Touch End");
            touchActive = false;
        });
        elem.addEventListener("touchmove", function (event) {
            console.log("Touch Active: %s", (touchActive) ? "Yes" : "No")
            if(touchActive){
            }
            else{
            }
        });
        </script>
    </body>
</html>

I had no issues with the touchstart/touchend using the iOS Simulator. So, a few things.

  1. Is it necessary to track touchstart/touchend on a mobile device when touchmove is only going to be dispatched when somebody is actively touching the device?
  2. More of a UX issue -- be careful about preventDefault on touchmove as this will prevent scrolling. Blocking default browser behavior can be very problematic for everybody.
  3. Adding console logging like I did can help you debug issues, that might be the best way to figure out if the issue is the event dispatch itself or something that you've done on the page (e.g. overlapping elements).

Upvotes: 0

Related Questions