Monaca Onsen UI Discord Chat Github Repo

onTouch events conflict when using with Polymer



  • When using OnsenUI with Polymer, there seems to be a conflict between the onTouch event listeners. For example, if I use the ons-switch component inside a Polymer element, the switch does not move when it is clicked/tapped. This, I have found, is due to the ‘click’ method of ons-switch being called twice. It is called once from onTouchHandler in gesture-detector.js and then again from _handleNative in Polymer’s gestures.html. This has the effect of the switch doing nothing, as it switches rapidly one way and then back the other.

    Is there a way to disable the onTouch handling in OnsenUI? At the moment I have fixed it by commenting out (or removing) the following lines in gesture-detector.js:

     // Add touch events on the document
     // Event$1.onTouch(GestureDetector.DOCUMENT, EVENT_MOVE, Detection.detect, opts);
     // Event$1.onTouch(GestureDetector.DOCUMENT, EVENT_END, Detection.detect, opts);
    

    However, I’m not sure what other effects this may have?

    Thanks.
    Mark


  • Onsen UI

    @markh That might affect other components so perhaps it would be better to modify switch’s code instead. Maybe we should implement some timestamp check to avoid toggling it too fast. There is actually a check like this in the last versions but maybe for a different situation.



  • @Fran-Diox The timestamp check is in the _onClick handler. This is never called in the situation I described. The stack trace for the first ‘click’ call from GestureDetector is:

    click (ons-switch.js:175)
    triggerEvent (gesture-detector.js:1321)
    tapGesture (gesture-detector.js:1852)
    triggerGesture (gesture-detector.js:1019)
    each (gesture-detector.js:261)
    detect (gesture-detector.js:1016)
    doDetect (gesture-detector.js:737)
    onTouchHandler (gesture-detector.js:657)
    

    and then the subsequent ‘click’ call via Polymer:

    click (ons-switch.js:175)
    _fire (gestures.html:589)
    forward (gestures.html:952)
    click (gestures.html:921)
    _handleNative (gestures.html:377)
    

    Therefore, to solve this issue, there would need to be an additional timestamp check in the ‘click’ method of ons-switch.

    Thanks



  • OK, I’ve had a bit more of a play with this and have now got ons-switch fully working within a Polymer element. This is what I had to do:

    1- First I uncommented the ‘onTouch’ lines that I detailed above.

    2- I changed the ‘click’ method of ons-switch to:

    key: 'click',
    value: function click(ev) {
        if (!this.disabled && (!this._lastTimeStampClick || ev.timeStamp - this._lastTimeStampClick > 10)) {
            this.checked = !this.checked;
            this._emitChangeEvent();
          }
          this._lastTimeStampClick = ev.timeStamp;
        }
    

    This uses a timestamp parameter to ensure that the switch is not switched if ‘click’ gets called twice quickly in succession, (once from OnsenUI and then from Polymer). It’s a bit hacky but seems to work.

    3- I also set the timestamp in the _onRelease handler so the same double switching did not happen after a drag.

    if (this.checked !== previousValue) {
        this._emitChangeEvent();
        this._lastTimeStampClick = e.timeStamp;
    }
    

    4- I had to add a listener for the ‘release’ event to the ons-switch component. The existing document listener did not get fired when the switch was inside a Polymer element, probably due to encapsulation.

    function _onHold(e) {
    ...
    document.addEventListener('release', this._onRelease);
    this.addEventListener('release', this._onRelease);
    ... 
    
    function _onDragStart(e) {
    ...
    document.addEventListener('release', this._onRelease);
    this.addEventListener('release', this._onRelease);
    ...
    
    function _onRelease(e) {
    ...
    document.removeEventListener('release', this._onRelease);
    this.removeEventListener('release', this._onRelease);
    ...
    

    Doing all this gets the switch working. I don’t know how many other components will have problems. It would be great if the OnsenUI components worked inside Polymer elements without any modifications. I don’t think it would be too much work.

    Thanks


  • Onsen UI

    @markh Thanks for the research! Yep, we should actually fix incompatibilities. Right now we are focusing in improving website and docs. Let’s see if after that we can make this.



  • @Fran-Diox Yes, it would be great if OnsenUI is made fully compatible with Polymer. After all, Polymer is a very good fit for the web components style that OnsenUI uses. Even better, would be Polymer versions of all the components. I did see a blog post about this on your site somewhere but don’t know whether it is something you are planning in the future?