Делаю блок scrollspy. который должен следить, находится ли блок в видимой зоне страницы. Блок подписывается на скролл
this.bindToWin('scroll', throttle(this._onScroll, this.pause, this));
получается, куча блоков подписанных на scroll, что в итоге тормозит. Пробовал задать live обработчик, с помощью liveBindTo(BEMDOM.win, 'scroll', callback)
но реакции на события нет. Как правильно подписаться на события вне блока?
Наверное, правильнее подписываться на скролл единожды, а дальше передавать событие во все активные инстансы блока.
Т.е., как-то так:
@zxqfox спасибо, сейчас попробую. Я как раз и хотел сделать подписку единожды. Единственно меня смущает this в статических методах...
К сожалению, не получилось.
this
в статических методах - функция. Следовательно,не прокатывает. Так что вопрос с подпиской по прежнему актуален
this
в статических методах это сам класс (тож самое, что иthis.__self
в динамических).Еще есть вариант:
Я лишь имел ввиду, что console.log(this) в статическом методе выдает
Это нормально ;-) У функций тоже есть методы. А функция он только потому, что из него создаются инстансы объекта.
Я далеко не эксперт js, о таком слышу впервые...
Ну, если коротко, то в js все объект:
Сделай так:
И открой в браузере, внутри live дебаггер остановится, и в консольке поиграйся с this.
@kompolom По поводу исходного вопроса топика. Верно ли я понимаю задачу, что на странице есть N блоков, которые должны в момент их появления/исчезновения из вьюпорта как-то реагировать? Если так, то я не очень понимаю, что здесь можно сэкономить. Ведь у каждого блока свои координаты/размеры/реакция на появление во вьюпорте и логично ожидать, что каждый из них сам подпишется. Ну и тормозит же не сама подписка, а обработчик? Но его придется вызывать для каждого блока в любом случае, верно?
Не знаю исходной задачи, но возможно будет полезна библиотека waypoints
@tadatuta Да, задача тригерить события на блоке при появлении/исчезновении.
@tadatuta Ты хочешь сказать что количество подписок никак не повлияет на производительность?
@kompolom Я вижу 2 принципиально разных варианта решения задачи:
scrollspy
, каждый из них сам следит за своей видимостью и сам знает, как реагировать на ее изменение. В этом случае экономить нечего.Я пробовал вариант 1. - не понравилось тормозами. Хочу сделать по второму варианту. Мне кажется так быстрее все же. при этом хочу не вешать этот блок на
page
а миксовать к тем блокам, которые его реально используют, при этом оставив один обработчик. Насколько я понимаю, это можно реализовать черезlive
события и методы. Примерно как @zxqfox предлагал выше.Всем спасибо за помощь. Вот что получилось.
Если у кого то найдется время на ревью, буду очень благодарен.
@kompolom
Может лучше
getOffset
?Я бы приватным свойствам добавил
_
в начало.Как и методам
без hasOwnProperty в ie будет не айс, я бы пересчитывал единожды и в массив собирал ключи. Операция добавления листенера, вроде как, редкая, а бегать по нему часто.
Еще я бы этот кусок переписал как-то иначе. Сложноватый.
В остальном, вполне годно. Может быть еще в логике что-то можно улучшить, надо подумать ;)
@zxqfox Спасибо, в ближайшее время допилю. Не знаю пригодится ли такой блок кому то еще. Может в отдельный репозиторий оформить его?
Пригодится, если будет сделан хорошо. В целом функционала там не много, но много подводных камней, которые требуют проработки. Поэтому, я только за ;-). Когда-нибудь еще появится npm для bem библиотек — и такие микроблоки там будут очень кстати.
upd В общем, пока жду в результата выдачи команды:
bower search 'bem-'
:fire:Добавил в bower
bem-scrollspy
А bindToWin откуда идёт? Попробовал его повесить в "коробочной" версии - ничего не заработало.
https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/__dom/i-bem__dom.js#L11 https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/__dom/i-bem__dom.js#L428
@Guria
Это как?
@kompolom без подключения разных модулей (блоков в зависимостях)
@Guria, спасибо за наводку :) Понял свою ошибку.