bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Когда hovered блока влияет на состояние hovered внутренного блока. События в js #100

Open voischev opened 9 years ago

voischev commented 9 years ago

Записал видео что бы было понятно. https://yadi.sk/i/OWFoBa18cP3j4

Это два самостоятельных блока, но в одном состоянии блока more может использоваться блок button над которым хочется производить какие то действия в зависимости от состояния блока родителя. Сейчас есть баг, он заключается в том что, когда нет hover на button то соответственно модификатор этого блока убирается. Но остается hover на блоке родителе more который должен транслировать этот hover на внутренний блок button

Как сделать правильно, что бы было ожидаемое поведение? Не хочу через стили.

Написал такой код:

modules.define('more', ['i-bem__dom', 'control'], function(provide, BEMDOM, Control) {

provide(BEMDOM.decl({ block : this.name, modName : 'type', modVal: 'link', baseBlock : Control }, {
    onSetMod : {
        'js' : {
            'inited' : function() {
                this._button = this.findBlockInside('button');
            }
        },
        'hovered' : {
            'true' : function() {
                this.__base.apply(this, arguments);
                this._button.setMod('hovered');
            },
            '' : function() {
                this.__base.apply(this, arguments);
                this._button.delMod('hovered');
            }
        }
    }
}));

});
tadatuta commented 9 years ago

Конкретно данный код можно улучшить в 2 местах:

  1. Применить live-инициализацию.
  2. Написать общий обработчик на hovered:
{
    hovered: function(modName, modVal) {
        this.__base.apply(this, arguments);
        this._button.setMod(modName, modVal);
    }
}

А уж насколько правильно само желание эмулировать состояние hovered — решать тебе. Как по мне, контрол на видео — это единый блок, у которого необходимая визуальная реакция должна задаваться просто через

.button_type_more:hovered .button__arrow {}
voischev commented 9 years ago

@tadatuta на видео не видно, но в дизайне это очень самостоятельных блока. И в одном из состояний more есть button

Не совсем понял

  1. Лайф инит применить для того что бы buttonинициализировать внутри? Как это будет связано с моей задачей?
  2. из-за кажется лишней скобочки, не совсем понял куда это нужно написать.
tadatuta commented 9 years ago
  1. live применить, чтобы блок инициализировался не в момент загрузки страницы, а в ответ на наведение мыши.
  2. это реакция на изменение модификатора hovered в любое значение (скобку добавил).
voischev commented 9 years ago

это реакция на изменение модификатора hovered в любое значение (скобку добавил).

@tadatuta что-то не работает как ожидается ((( всеравно когда мышка выходит за button внутри more с button убирается модификатор hovered

tadatuta commented 9 years ago

@voischev я неправильно прочитал твой исходный вопрос :( изменения, которые предложил никак не меняют логику твоего исходного кода, только лишь чуть-чуть экономят на отложенной инициализации и строчках кода.

Умозрительно, происходит следущющее:

  1. Мышь попадает в more, твой код выставляет _hovered на button.
  2. Мышь попадает на button, внутри уже благодаря коду button происходит попытка снова выставить _hovered, для пользователя все ок.
  3. Мышь выходит из button, обработчик удаляет _hovered.

Чтобы этого не происходило, ты можешь выставлять для button внутри more некий модификатор, в котором отписываться от исходной реакции на ховер (она реализована в https://github.com/bem/bem-components/blob/v2/desktop.blocks/control/control.js#L16-L33)