Как стать автором
Обновить

Комментарии 17

Как раз на прошлых выходных пользовался MutationSummary в рамках хаккатона. Хорошая вещь, но разочарований больше, чем радостей. На видео один из разработчиков показывает DOM-зеркало: на одной странице поисходят изменения, а в другой они полностью повторяются. На практике взять код «как есть» не удалось, т.к. он предполагает, что доступ к оригиналу возможен через DOM API — либо это фреймы на одной странице, либо как в примере — связь через расширение браузера. Мы же хотели «достучаться» до странице на другом устройстве, и к сожалению, так «зеркало» не работает.

А настраивать mutation summary руками оказалось тоже неприятно. Если у вас простой случай — например, текст внутри элемента меняется или меняются атрибуты — то все замечательно. Мы же работали с rich-текстом через contentEditable, и там простое изменение часто влечет к появлению 5--6 «мутаций» одновременно.

В итоге остались баги, которые поправить вовремя не удалось. И как следствие, низкие оценки :(
Может проблема была в библиотеке, а не в самих Observer-ах?
Надеюсь вы доделаете все до конца и расскажете здесь, в чем же было дело.
Эффективно связать две страницы в рамках одного браузера, если они не кросдоменны, можно посредством localStorage и ивента onstorage. Вся соль этого ивента, что он не срабатывает на странице, которая непосредственно произвела работу со стореджем, а на других страницах этого же сайта, открытых в этом же браузере — срабатывает.

upd: извините, не заметил, что вам надо было достучаться до страницы на другом устройстве.
А MutationObserver из Polymer не пробовали?
Нет, не пробовал, хотя с Полимером работаю. Посмотрю, спасибо за наводку.
Написал свой велосипед и радостно его использую в облачном плеере Listen! для Google Chrome, удобство радует неимоверно. При изменении DOM подписываюсь на созданные ноды + удаляю обработчики с удаленных.
Пожалуйста, не надо использовать mutationObserver в продакшне, не в рамках библиотек. Он реально очень низкоуровневый.
В чем, собственно, дело: по сути единственный способ изменить дом-дерево это код. Код, который написал разработчик.
Если разработчик не способен архитектурно построить код так, чтобы реагировать на внесенные этим же кодом изменения в дом-дерево — я бы не назвал разработчика грамотным.
Пользователь максимум может взаимодействовать с value инпутов и :checked у чекбокса — это из изменений структуры. Ну ладно, сейчас появились drag-n-drop события, но они тоже обрабатываются на жс, нельзя просто так все править, без создания базы для кода. Так что на исключение не тянет. Ладно, если говорить совсем откровенно — есть и contenteditable, но он до сих пор не кроссплатформенный, да и я честно еще не встречал его нигде, и, подозреваю, нескоро встречу.

Mutation events необходимы для веб-компонентов, без них невозможно построить триггеры на добавление кастомного элемента в дом-дерево, что лишает их большинства преимуществ. Mozilla и Google вместе разрабатывали этот стандарт, и, конечно же, им хотелось сделать для себя разумные и простые решения. Кроме этого единственное, где реально имеет смысл использовать MutationObserver не в качестве очень грязного хака — это библиотеки, переводящие большую часть кода в декларативное состояние, например, Angular и ему подобные с директивами.

А так — не надо пользовать. Не только даже потому что это почти невозможно отлаживать, но еще и потому что у MutationObserver до конца не выясненные глюки. Например, мало кому известно, что в хроме(во всяком случае раньше было так) на четвертом или пятом колбэке подряд, когда в самом колбеке редактируется содержимое элемента, иногда обсервер захлебывается и начинает пропускать события. При этом этот эффект наблюдается только на ванилле, jquery как-то его обходит.
Если разработчик не способен архитектурно построить код так, чтобы реагировать на внесенные этим же кодом изменения в дом-дерево — я бы не назвал разработчика грамотным.

Не очень понятно почему. Логично, по-моему, использовать для реакции на изменения DOM события, а для их обработки паттерн «Наблюдатель». И как-то не совсем логично реализовывать свой механизм параллельно имеющемуся нативному.
В чем, собственно, дело: по сути единственный способ изменить дом-дерево это код. Код, который написал разработчик.

Не всегда. Иногда код встраивается в страницу и должен следить за изменениями на ней.
Например, мы в RedHelper довольно успешно используем MutationObserver для cobrowsing'а. Так что в продакшене использовать можно, а иногда даже нужно.
Что есть cobrowsing? Это когда кто-то подглядывает за тем, что происходит в браузере другого?
Это реализация на уровне библиотеки все же, и скорее всего вы ее довольно долго писали, и выявили кучу интересных особенностей поведения. Я говорил про конечных разработчиков, которые не хотят писать нужные вызовы на внесения правок в верстку, и вместо этого пользуют мутейшнобсервер.
contentEditable — очень распространенная штука. Его поведение по умолчанию — да, не кроссплатформенное, — но его можно «причесать».

Twitter и Google+, например, использует contentEditable для поля новых постов. В Outlook.com поле ввода текста письма — тоже contentEditable. В Gmail тоже так было. Первые версии Google Docs и других онлайн-редакторов были или остаются на contentEditable. Куча платформ для блогов и CMS тоже его используют.

Так что вы его наверняка встречали.
Крутая штука, использовал в плагинчике, весьма успешно. Упрощает API в разы: не нужны всякие методы add, etc, с DOM можно работать напрямую, а плагин возьмет всю работу на себя.

Проблема в том, что под старые браузеры (оперу и IE в первую очередь) надо писать жуткий фолбэк в виде сначала обработки событий DOMNodeChanged, DOMNodeRemoved, ..., а затем и вообще реализуя соответствующие методы.
Хотя сейчас ситуация уже получше: caniuse.
MutationObserver — штука прикольная, но к сожалению им нельзя отловить reflow. Предположим, я хочу отследить позицию элемента на странице, она может измениться, например из-за удаления соседней ноды, к сожалению, решить эту проблему не навешивая MutationObserver на каждый элемент либо без регулярной проверки в setInterval, у меня не получилось. Если кто-нибудь подскажет красивое решение, буду благодарен.
ну как бы можно повесить на body с атрибутом subtree — будет эмиттится на любое изменение.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории