bem-components icon indicating copy to clipboard operation
bem-components copied to clipboard

[touch] button: Does not emit click on first try

Open tadatuta opened this issue 7 years ago • 8 comments

tadatuta avatar Apr 16 '17 14:04 tadatuta

If you change the type of event from pointerclick to click in method _onPointerRelease: https://github.com/bem/bem-components/blob/v5.0.0/common.blocks/button/button.js#L117 , then it works. So, I guess problem in https://github.com/bem/bem-core/blob/v4/common.blocks/jquery/__event/_type/jquery__event_type_pointerclick.js

rtemision avatar Apr 18 '17 05:04 rtemision

https://github.com/bem/bem-components/blob/v3/common.blocks/button/button.js#L106

У меня почему-то подозрения на это место. Подписка делается только тогда, когда событие всплыло уже на самый верх документа.

У нас на проекте профиксил локально переопределив 3 метода. Только не знаю как правильно должна быть подписка на pointerclick (bindTo или bindToDoc) оно и так и так работает нормально, но не зря ведь подписка на клик была после всплытия...

    _onPointerPress : function() {
        this.bindTo('mousedown', this._onMouseDown);
        if(!this.hasMod('disabled')) {
            this._isPointerPressInProgress = true;
            this
                .bindToDoc('pointerrelease', this._onPointerRelease)
                .bindToDoc('pointerclick', this._onPointerClick) 
                .setMod('pressed');
        }
    },

    _onPointerRelease : function(e) {
        this._isPointerPressInProgress = false;
        this.unbindFromDoc('pointerrelease', this._onPointerRelease);

        if(e.originalEvent.type === 'pointerup' && dom.contains(this.elem('control'), $(e.target))) {
            this._focusedByPointer = true;
            this._focus();
            this._focusedByPointer = false;
        } else {
            this._blur();
        }

        this.delMod('pressed');
    },

    _onPointerClick : function() {
        this
            .unbindFromDoc('pointerclick', this._onPointerClick)
            ._updateChecked()
            .emit('click');
    },

Если решение годное, могу прислать PR.

//cc @tadatuta

belozer avatar May 23 '17 01:05 belozer

Я локально решил, выпилив из jquery__event_type_pointerclick.js условие для ios.

rtemision avatar May 23 '17 14:05 rtemision

@rteamx проблема не в pointerclick, а в моменте его подписки.

belozer avatar May 23 '17 14:05 belozer

@belozer ну да, согласен.

rtemision avatar May 23 '17 17:05 rtemision

Тесты правда упали с таким решением...

Но если исключить вообще историю про pointerclick, то тесты зелёные и отрабатывает правильно.

    _onPointerRelease : function(e) {
        this._isPointerPressInProgress = false;
        this.unbindFromDoc('pointerrelease', this._onPointerRelease);

        if(e.originalEvent.type === 'pointerup' && dom.contains(this.elem('control'), $(e.target))) {
            this._focusedByPointer = true;
            this._focus();
            this._focusedByPointer = false;
            this
                ._updateChecked()
                .emit('click');
        } else {
            this._blur();
        }

        this.delMod('pressed');
    },

belozer avatar May 29 '17 21:05 belozer

+@veged +@awinogradov

veged avatar Jan 10 '18 13:01 veged

Доопределение button.js с заменой pointerclick на click

modules.define(
    'button',
    ['i-bem-dom', 'jquery', 'dom'],
    function(provide, bemDom, $, dom, Button) {

        provide(bemDom.declBlock(Button,{

            _onPointerRelease : function(e) {
                this._isPointerPressInProgress = false;
                this._domEvents(bemDom.doc).un('pointerrelease', this._onPointerRelease);

                if(e.originalEvent.type === 'pointerup' && dom.contains(this.findMixedElem('control').domElem, $(e.target))) {
                    this._focusedByPointer = true;
                    this._focus();
                    this._focusedByPointer = false;
                    this._domEvents().once('click', this._onPointerClick);
                } else {
                    this._blur();
                }

                this.delMod('pressed');
            },

            _onPointerClick : function() {
                this.__base();
            },


        }));

    });

ijakparov avatar Aug 28 '18 13:08 ijakparov