简体   繁体   中英

Polymer 1.5/iOS: How to stop event propagation over iron-pages

We have a one page app which uses iron pages and express-router to navigate. In the browser and on android it works perfectly, on iOS however, we have a bug. The problem occurs if we switch pages by a button press. If the button is exactly over an input text field element (read: in the same position, but on the next iron-page) the input element gains focus directly after the page switch.

We used to have this problem as well with two buttons in the same position but this was solved by changing all on-clicks to on-taps.

Things we have tried so far:

  • Adding event.stopPropagation to the on-tap event
  • Including fastclick.js to prevent click delays (this worked partially when on-clicks were still in place but was made obsolete with on-tap)

Note that we have experienced this problem since Polymer 1.0 all through 1.5.

I reproduced your symptoms on an iPad Air 2, and trying e.stopPropagation() , e.preventDefault() , and returning false all had no effect. I'm not sure whether this is actually a Polymer problem.

I have a couple [hacky] workarounds to employ during the page-switch:

  • Option 1: Delay the page-change by 400ms. If your button has a ripple effect, the delay is masked by the animation.

    codepen

  • Option 2: Disable the input and re-enable it after a 400ms delay. This prevents the input from picking up the tap event, but has the disadvantage that the disabled state could be noticeable (perhaps a lesser evil than your current problem).

    codepen

Thanks @tony19, for the input.

We wanted to avoid delays, so I researched a bit more and ultimately fixed the problem. To answer my own question: the ultimate solution did lie in the FastClick library.

Basically what happens is that the tap event is fired immediately, but it doesn't replace the click event. Rather, the click event still fires, but with the original 300ms delay. This delayed click event thus fires on the newly displayed 'page' and triggers the input-field (or button had it been there) at the same xy coordinates.

Adding the FastClick library once again solves this thanks to some updates in the library. However, it breaks some items that need the original click, such as Google Autocomplete. A basic solution to exclude FastClick is to instead apply it as:

FastClick.attach(document.body, {
    excludeNode: 'something', });

This, however, only works for that node and not possible children. As such, to fix everything for input fields with Google's Autocomplete as well is done using:

// Disable FastClick for the children of a google auto-
// complete component.
var needsClick = FastClick.prototype.needsClick;
FastClick.prototype.needsClick = function(target) {
    if ( (target.className || '').indexOf('pac-item') > -1 ) {
        return true;
    } else if ( (target.parentNode.className || '').indexOf('pac-item') > -1) {
        return true;
    } else {
        return needsClick.apply(this, arguments);
    }
};

// Remove click delay on iOS. As such, removing differences
// in timing between click and tap, thereby avoiding the
// fall-through problem.
FastClick.attach(document.body);

I will now close this thread, but I thought it'd be nice to leave this as reference for anyone else experiencing the problem.

Understand that it affected Polymer 1.0 to 1.5. Just to confirm that we experienced the same behaviour in Polymer 1.6 and the following fixes it.

_onTap: function(event) {
    event.preventDefault();
    event.stopPropagation();
}

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