Но сама идея, лежащая в основе DOM Mutation Events казалась привлекательной и поэтому в сентябре 2011 г. группа инженеров Google и Mozilla представила предложение о DOM MutationObserver, с похожей функциональностью, но улучшенной производительностью. Это новое DOM-API доступно начиная с версий: Firefox 14, Chrome 18, IE 11, Safari 6 (caniuse — caniuse.com/mutationobserver)
В простейшем случае MutationObserver используется примерно так:
// выбираем элемент
var target = document.querySelector('#some-id');
// создаем экземпляр наблюдателя
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// настраиваем наблюдатель
var config = { attributes: true, childList: true, characterData: true }
// передаем элемент и настройки в наблюдатель
observer.observe(target, config);
// позже можно остановить наблюдение
observer.disconnect();
Ключевым преимуществом новой спецификации перед устаревшей DOM Mutation Events является эффективность. При наблюдении за узлом DOM, ваша функция обратного вызова не сработает до тех пор, пока изменения DOM полностью не завершатся. Когда же callback сработает, в него будет передан итоговый список изменений DOM, пробежавшись по которому можно будет как-то отреагировать на изменения.
Так же предполагается, что в коде понадобится как-то обрабатывать результаты, переданные наблюдателем, чтобы реагировать именно на нужные нам изменения. Вот небольшой пример наблюдателя, прослушивающего изменения редактируемого на месте упорядоченного списка:
<!DOCTYPE html>
<ol contenteditable oninput="">
<li>Press enter</li>
</ol>
<script>
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var list = document.querySelector('ol');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
var list_values = [].slice.call(list.children)
.map( function(node) { return node.innerHTML; })
.filter( function(s) {
if (s === '<br>') {
return false;
}
else {
return true;
}
});
console.log(list_values);
}
});
});
observer.observe(list, {
attributes: true,
childList: true,
characterData: true
});
</script>
Для того, чтобы вы могли посмотреть код в деле, я разместил его на jsbin:
Если вы поигрались с кодом в песочнице, вы, наверное, отметили одну особенность: функция обратного вызова срабатывает только тогда, когда вы нажимаете “ввод” на каком-либо элементе списка — по существу, это из-за того, что ваши действия приводят к добавлению или удалению узла DOM. Это важнейшее отличие от других техник, таких как подписка на нажатие клавиш, или клики мышью. MutationObservers работает не так, как все эти техники — здесь срабатывание происходит только при изменении DOM, а не как реакция на события, инициируемые JS, или действиями пользователей.
Итак, а где же это использовать?
Не думаю, что все программисты тут же ни с того ни с сего, все побросают, и начнут встраивать MutationObservers в свой код. Вероятно больше всего данный API подойдет разработчикам JS-фреймворков, для реализации чего-то нового, или того, что не было раньше реализовано из-за проблем с производительностью. Так же данная техника пригодиться, если вы используете какой-либо фреймворк, изменяющий DOM, и вам необходимо реагировать на эти изменения (без использования костылей, типа setTimeout). Ну и последнее — это разработка браузерных расширений.
Ресурсы:
От переводчика: материалу больше года, но что-то уж больно мало на русском о MutationObserver — может кому пригодится.
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. FiveFilters.org recommends: March Against Mainstream Media (More info).
Комментариев нет:
Отправить комментарий