0

I have a small sample app here: http://codepen.io/DouglasGlover/full/OPpMaV/

This is a mobile-only experience (though it technically functions on desktop as well). Only concerned about mobile here.

The intended behavior is that a user touches their phone, and holds their finger down on the phone (anywhere on the screen). As they do this, the counter goes up. When they let their finger come off the phone, it stops the counter.

There is a use case where a user may (perhaps accidentally) rotate their phone just enough that the site's orientation switches. Currently, if that happens, the counter continues to count infinitely upwards. Subsequent touches initiate a second touch event, which makes it go faster (I can deal with that, fixing the initial issue should fix this).

So my problem seems to be that upon switching orientation, the touch event "dies". So "touchstart" fires initially, and I'm waiting for a "touchend" which never gets to fire.

Ideally, the user can touch the phone, then rotate it without consequence (and without breaking the experience).

Here's the prototype code as it stands now...

HTML:

<div class="touchspace"></div>
<div class="ls">
  <div class="counter">0</div>
</div>
<div class="pt">
  <div class="counter">0</div>
</div>

CSS:

body{ margin: 0; }
.ls, .pt{ display: block; width: 100vw; height: 100vh; }
.ls{ background: lightblue; }
.pt{ background: lightgreen; }
.counter{ display: block; position: relative; top: 10%; font-weight: bold; color: white; font-size: 20vw; width: 20%; margin: 0 auto; }
.touchspace{ display: block; position: absolute; bottom: 0; right: 0; background: transparent; z-index: 999; background: red; width: 500vw; height: 500vh; opacity: .5; }

@media all and (orientation:landscape){ .ls{ display: none; } }
@media all and (orientation:portrait){ .pt{ display: none; } }

JS:

var counter = 0,
interval;
$(".touchspace").bind("touchstart mousedown",function(){
  interval = window.setInterval(function(){
    counter++;
    $(".counter").html(counter);
  }, 1000);
});

$(".touchspace").bind("touchend mouseup",function(){
  window.clearInterval(interval);
});
Douglas
  • 705
  • 3
  • 11
  • 26

3 Answers3

0

Can you bind the orientationchange event to trigger an end and a start, or will that cause too much of a break in the user experience.

something like:

$(window).on('orientationchange', function () {
   $('.touchspace').trigger('touchend');
   $('.touchspace').trigger('touchstart');
});
Dave Goten
  • 701
  • 4
  • 13
  • I might be able to work with that. Problem is that there are functions that are supposed to happen when touch ends. That said, I could use a second check (a true/false check, perhaps) to make it only run stuff when I mean for it to. I'll try this out, thanks. – Douglas Jan 13 '15 at 20:23
  • Unfortunately this did not help. The fact that the user's finger is still on the screen seems to be lost completely on orientation change. – Douglas Jan 16 '15 at 16:46
  • Then, there's always the not so fun, load the interval on page load. Have the interval function check a sentinal value like, isTouching. Initialize it as false. On touchstart set isTouching = true, ontouchend make it false. So the interval never stops running, but it just doesn't do anything when you haven't triggered a touch start. – Dave Goten Jan 16 '15 at 16:52
0

Inside the interval, check if the initial orientation is changed and clear the interval. Not able to test the code as I do not have the environment!

var counter = 0,
isOrientationChanged=false,
interval;
$(".touchspace").bind("touchstart mousedown",function(){
  interval = window.setInterval(function(){
    counter++;
    $(".counter").html(counter);
    //check if orientation is changed, clear the interval & reset the flag
    if(isOrientationChanged)
    { 
        isOrientationChanged=false;
        window.clearInterval(interval);
    }
  }, 1000);
});

$(".touchspace").bind("touchend mouseup",function(){
  window.clearInterval(interval);
});

$(window).on('orientationchange', function () {
  isOrientationChanged=true;//mark the flag true
});
Vijay
  • 2,965
  • 1
  • 15
  • 24
  • The biggest problem I'm having is that orientationchange isn't initiated until AFTER the device redraws the DOM. When mobile device orientation is changed, a redraw happens which causes the "toucharea" to become nonexistent for a split second, causing a touchend event. I can unbind touchend from the div on orientationchange, but this happens AFTER the redraw. It's almost looking to be impossible, and I HATE saying that. – Douglas Jan 20 '15 at 15:50
  • I am sorry Douglas, I am not able to help in detail as I don't have the proper environment setup. Would ask to my developer friends to help you out asap. :) – Vijay Jan 20 '15 at 16:11
0

I've spend last 2 hours trying to achieve it. It seems that it is unable right now - current prior of art. "orientationchange" loses focus of the element.

Ender
  • 158
  • 1
  • 9