一个元素有一个 javascriptstyle
对象,其中包含 css 样式的不同名称和值。我想在每次这个对象改变而不使用 polling时触发一个函数。有什么方法可以跨浏览器兼容并且可以与第三方代码一起可靠地工作(因为假设您正在提供插入脚本)?绑定一个 javascript 事件,比如DOMAttrModified
or 是DOMSubtreeModified
不够的,因为它们在 Chrome 中不起作用。
在 DOM 元素的样式对象更改后,您可以使用 javascript 钩子触发器吗?
编辑 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);
});
参考:
- 检测是否支持 DOMAttrModified
- DOMAttrModified for chrome
- 突变观察者
- 为什么我们应该避免使用 Mutation 事件?
- onPropertyChange IE
Mutation Observers 是 DOM4 中突变事件的建议替代品。它们预计将包含在 Firefox 14 和 Chrome 18 中
浏览器支持:
onpropertychange
- 支持 IE(在 IE 7 中测试)
DOMAttrModified
- 支持 IE 9、FF 和 Opera
MutationObservers
- 非常新,在Chrome 18 中运行良好。不确定它在多大程度上受支持并且尚未在 Safari 中进行测试。
感谢@benvie添加有关 WebkitMutationObserver 的信息
编辑2:
如果你还想使用mutation observer
,使用这个库:mutation-summary
编辑:
正如我在下面的回答中所说,并感谢 Vega 的评论,使用诸如object.watch
或mutation observers
不推荐在大型应用程序中使用的东西。这是MDN 的实际报价:
一般情况下,您应该避免使用
watch()
和unwatch()
在可能的情况下。这两种方法仅在 Gecko 中实现,它们主要用于调试用途。此外,使用观察点 对性能有严重的负面影响,尤其是在全局对象上使用时尤其如此,例如窗口。您通常可以使用 setter和getter或代理代替。有关详细信息,请参阅兼容性。警告
因此,如果跨浏览器兼容性在您的检查列表中,我再次强烈建议覆盖对象的setter
s 和getter
s style
。
object.watch
在跨浏览器解决方案中
使用并牢记这些:
你可以覆盖getter
和setter
元素的方法style
过于对象。
有一个 jQuery 插件可用于此,jQuery watch
我发现这个小插件可以做到这一点,并且可以对其进行更改以添加您希望的任何突变……甚至 scrollHeight 更改侦听器。
插件:http : //www.jqui.net/jquery-projects/jquery-mutate-official/
这是演示:http : //www.jqui.net/demo/mutate/
即使对于所有最现代的浏览器,也没有跨浏览器的方式来实现这一点。您必须通过一个可以触发事件侦听器的函数来路由所有 css 样式更改。这将是最干净的方法。
在对类似问题的回答中,有人建议如果您知道样式设置交互将通过标准接口执行(即始终使用 jQuery 等),则建议在调用库方法时触发自定义事件。
这将允许更广泛的支持矩阵,但如果在不使用库方法的情况下执行,则会忽略任何属性更改。这种方法似乎也不适用于本地 setter,因为它们不能总是被依赖。