Question

I'm experiencing a strange issue w/ a Backbone.js app. In my main view, I want to capture all input events that occur over the view and route them to input handler methods. I also have some links in the view that navigate to other parts of the app. Relevant (CoffeeScript) code:

events:
    'click a.quit': 'quit'
    'mousedown': 'onActionStart'
    'mouseup': 'onActionEnd'
    'touchstart': 'onActionStart'
    'touchmove': 'onActionMove'
    'touchend': 'onActionEnd'

The event handling works as expected in desktop Safari. When I click the "quit" link, the "onAction__" methods fire, and then the "quit" method is called. However, on Mobile Safari, the "quit" method doesn't get called. If I modify the touch event selectors to only respond to a smaller area in the view (i.e. an element not overlapping the link), then it works as expected. (All the methods that are triggered via user input have preventDefault() calls in them, but that shouldn't stop the events from bubbling.) Is this a known Mobile Safari issue?

Was it helpful?

Solution

Well, I ended up turning the "events" object into a function and doing basic browser sniffing to detect platforms with touchscreens. Turning 'click a.quit': 'quit' into 'mouseup a.quit': 'quit' gets called correctly, even though the Safari docs say

If the user taps a clickable element, events arrive in this order: mouseover, mousemove, mousedown, mouseup, and click

Here's my result:

    events: ->
        # Determine whether touchscreen or desktop
        agent = navigator.userAgent.toLowerCase()
        if agent.match(/ip(hone|od|ad)/i) or agent.match(/android/i)
            events = 
                'touchend a.quit': 'quit'
                'touchend a.reset': 'reset'
                'touchstart': 'onActionStart'
                'touchmove': 'onActionMove'
                'touchend': 'onActionEnd'
                'onscroll': 'preventDefault'
                'gesturestart': 'preventDefault'
                'gesturechange': 'preventDefault'
                'gestureend': 'preventDefault'
        else 
            events = 
                'click a.quit': 'quit'
                'click a.reset': 'reset'
                'mousedown': 'onActionStart'
                'mouseup': 'onActionEnd'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top