Можете ли вы иметь триггер javascript после изменения объекта стиля элемента DOM?
Элемент имеет JavaScript style
Объект, который содержит разные имена и значения стилей CSS. Я хотел бы вызывать функцию каждый раз, когда этот объект изменяется без использования опроса. Есть ли способ сделать это так, чтобы он был кросс-браузерно-совместимым и надежно работал бы с сторонним кодом (потому что, допустим, вы предоставляете скрипт для вставки)? Привязка события JavaScript, как DOMAttrModified
или же DOMSubtreeModified
не хватит, потому что они не работают в Chrome.
6 ответов
Редактировать 4: Демо
$(function() {
$('#toggleColor').on('click', function() {
$(this).toggleClass('darkblue');
}).attrchange({
trackValues: true,
callback: function(event) {
$(this).html("<ul><li><span>Attribute Name: </span>" + event.attributeName + "</li><li><span>Old Value: </span>" + event.oldValue + "</li><li><span>New Value: </span>" + event.newValue + "</li></ul>");
}
});
});
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;
}
#toggleColor {
height: 70px;
width: 300px;
padding: 5px;
border: 1px solid #c2c2c2;
background-color: #DBEAF9;
}
#toggleColor span {
font-weight: bold;
}
#toggleColor.darkblue {
background-color: #1A9ADA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://meetselva.github.io/attrchange/javascripts/attrchange.js"></script>
<p>Click below div to toggle class darkblue.</p>
<div id="toggleColor"></div>
Редактировать 3: я собрал все это как плагин, который можно скачать с git attrchange, и вот демо-страница.
Изменить 2:
- Исправлено правильное имя в IE7 и IE8
Изменить 1:
- Обрабатывать несколько элементов
- Упорядоченные условия как MutationObserver, DOMAttrModified и onpropertychange для лучшей реализации.
- Добавлено измененное имя атрибута для обратного вызова.
Спасибо @benvie за отзыв.
ДЕМО: http://jsfiddle.net/zFVyv/10/ (протестировано в FF 12, Chrome 19 и IE 7.)
$(function() {
(function($) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
function isDOMAttrModifiedSupported() {
var p = document.createElement('p');
var flag = false;
if (p.addEventListener) p.addEventListener('DOMAttrModified', function() {
flag = true
}, false);
else if (p.attachEvent) p.attachEvent('onDOMAttrModified', function() {
flag = true
});
else return false;
p.setAttribute('id', 'target');
return flag;
}
$.fn.attrchange = function(callback) {
if (MutationObserver) {
var options = {
subtree: false,
attributes: true
};
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(e) {
callback.call(e.target, e.attributeName);
});
});
return this.each(function() {
observer.observe(this, options);
});
} else if (isDOMAttrModifiedSupported()) {
return this.on('DOMAttrModified', function(e) {
callback.call(this, e.attrName);
});
} else if ('onpropertychange' in document.body) {
return this.on('propertychange', function(e) {
callback.call(this, window.event.propertyName);
});
}
}
})(jQuery);
$('.test').attrchange(function(attrName) {
alert('Attribute: ' + attrName + ' modified ');
}).css('height', 100);
});
Ref:
- Определить, поддерживается ли DOMAttrModified
- DOMAttrModified для хрома
- Наблюдатель мутаций
- Почему мы должны избегать использования событий мутации?
- onPropertyChange IE
Наблюдатели мутаций - это предлагаемая замена мутационных событий в DOM4. Ожидается, что они будут включены в Firefox 14 и Chrome 18
Поддержка браузера:
onpropertychange
- поддерживается в IE (протестировано в IE 7)
DOMAttrModified
- поддерживается в IE 9, FF и Opera
MutationObservers
- очень новый и отлично работал в Chrome 18. Не уверен, насколько это поддерживается и еще предстоит проверить в Safari.
Спасибо @benvie за добавление информации о WebkitMutationObserver
EDIT2:
Если вы все еще хотите использовать mutation observer
, используйте эту библиотеку: mutation-summary
РЕДАКТИРОВАТЬ:
Как я сказал в своем ответе ниже и спасибо Vega за его комментарий, используя такие вещи, как object.watch
или же mutation observers
не рекомендуется использовать в больших приложениях. это актуальная цитата из MDN:
Как правило, вы должны избегать использования
watch()
а такжеunwatch()
когда возможно. Эти два метода реализованы только в Gecko и предназначены главным образом для использования при отладке. Кроме того, использование точек наблюдения оказывает серьезное негативное влияние на производительность, что особенно актуально при использовании глобальных объектов, таких как окно. Вместо этого вы обычно можете использовать сеттеры и геттеры или прокси. См. Совместимость для деталей.Предупреждение
Так что, если в вашем контрольном списке есть совместимость с разными браузерами, опять же, я настоятельно рекомендую переопределить setter
с и getter
с style
объект.
использование
object.watch
и имейте это в виду для кросс-браузерного решения:- Javascript Object.Watch для всех браузеров?
- object.watch polyfill
- Следите за изменениями свойств объекта в JavaScript
Вы можете переопределить getter
а также setter
методы элемента style
объект тоже.
Для этого есть плагин jQuery, часы jQuery
Я нашел этот маленький плагин, который делает именно это, и его можно изменить, чтобы добавить любую мутацию, какую вы пожелаете... Даже scrollHeight change listener.
Плагин: http://www.jqui.net/jquery-projects/jquery-mutate-official/
вот демо: http://www.jqui.net/demo/mutate/
Вы можете использовать attrchange плагин jQuery. Основная функция плагина - привязать функцию слушателя к изменению атрибутов HTML-элементов.
Даже для всех самых современных браузеров нет кросс-браузерного способа добиться этого. Вы должны были бы направить все ваши изменения стиля CSS через функцию, которая могла бы вызвать прослушиватели событий. Это был бы самый чистый метод.
В ответ на аналогичный вопрос было высказано предположение, что если вы знаете, что взаимодействие по настройке стиля будет выполняться через стандартный интерфейс (т. Е. Всегда с использованием jQuery и т. Д.), Было предложено запускать пользовательские события при каждом вызове библиотечного метода.
Это позволит использовать более широкую матрицу поддержки, но при этом любое изменение свойства будет игнорироваться, если оно выполняется без использования библиотечного метода. Также представляется, что такой подход не применим к собственным установщикам, поскольку на них нельзя всегда полагаться.