在 DOM 元素的样式对象更改后,您可以使用 javascript 钩子触发器吗?
Posted
技术标签:
【中文标题】在 DOM 元素的样式对象更改后,您可以使用 javascript 钩子触发器吗?【英文标题】:Can you have a javascript hook trigger after a DOM element's style object changes? 【发布时间】:2012-06-07 17:55:38 【问题描述】:一个元素有一个 javascript style
对象,其中包含不同的 css 样式名称和值。我想在每次该对象更改不使用轮询时触发一个函数。有没有办法以跨浏览器兼容的方式做到这一点,并且可以与第三方代码可靠地工作(因为假设您提供了一个插入式脚本)?绑定像 DOMAttrModified
或 DOMSubtreeModified
这样的 javascript 事件是不够的,因为它们在 Chrome 中不起作用。
【问题讨论】:
***.com/questions/4561845/… 我有一个答案,但是,您是针对古代浏览器吗?还是主要浏览器? @3p3r 我也针对旧版本的浏览器,但我肯定会对只针对新版本的解决方案感兴趣 @3p3r 但是不,我不关心没有人使用的旧浏览器,例如 Konqueror 或其他... @user730569 我有already answered,使用getter
和setter
以获得最佳性能
【参考方案1】:
即使对于所有最现代的浏览器,也没有跨浏览器的方式来实现这一点。您必须通过一个可以触发事件侦听器的函数来路由您的所有 css 样式更改。这将是最干净的方法。
【讨论】:
【参考方案2】:编辑 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 下载,这里是 demo page。
编辑 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);
);
参考:
-
Detect if DOMAttrModified supported
DOMAttrModified for chrome
Mutation Observer
Why should we avoid using Mutation events?
onPropertyChange IE
Mutation Observers 是 DOM4 中突变事件的提议替代品。预计它们将包含在 Firefox 14 和 Chrome 18 中
浏览器支持:
onpropertychange
- 在 IE 中受支持(在 IE 7 中测试)
DOMAttrModified
- 在 IE 9、FF 和 Opera 中受支持
MutationObservers
- 非常新,在Chrome 18 中运行良好。不确定它支持多远,尚未在 Safari 中进行测试。
感谢 @benvie 添加有关 WebkitMutationObserver 的信息
【讨论】:
谢谢!WebkitMutationObservers
的浏览器支持怎么样? (它在 chrome 和 safari 中可以追溯到多远?)onPropertyChange
呢?
MutationObservers 是非常新的,但在最近的 WebKit 和 Firefox 中得到支持。不过,它们是 DOM 修改事件的未来,我很高兴看到它们包含在这个答案中。 ++这个答案
哦,如果它也处理无前缀版本(Firefox 15 支持)会更好。 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
.
@benvie 我在哪里可以找到支持它们的特定浏览器版本?
isDOMAttrModifiedSupported
中不需要 attachEvent
分支:DOM 突变事件支持与 IE 中的 addEventListener
支持一致(两者都在 IE 9 中引入)。【参考方案3】:
EDIT2:
如果您仍想使用mutation observer
,请使用此库:mutation-summary
编辑:
正如我在下面的回答中所说,并感谢 Vega 的评论,不建议在大型应用程序中使用诸如 object.watch
或 mutation observers
之类的东西。这是来自MDN的实际报价:
通常你应该避免使用
watch()
和unwatch()
可能的。这两种方法仅在 Gecko 中实现,它们是 主要用于调试用途。此外,使用观察点 对性能有严重的负面影响,尤其如此 用于全局对象,例如窗口。你通常可以使用 setters 和 getters 或 代理。有关详细信息,请参阅兼容性。警告
因此,如果您的检查清单中有跨浏览器兼容性,我再次强烈建议覆盖style
对象的setter
s 和getter
s。
使用
object.watch
并牢记这些跨浏览器解决方案:
Javascript Object.Watch for all browsers?
object.watch polyfill
Watch for object properties changes in JavaScript
您也可以覆盖元素的style
对象的getter
和setter
方法。
有一个可用的 jQuery 插件,jQuery watch
【讨论】:
我认为 watch 使用轮询.. 并且 OP 正在寻找 不使用轮询的对象更改 @Vega 好吧,我不太了解 Gecko 的源代码,但我认为“轮询”OP 意味着手动setInterval
s,不是吗?【参考方案4】:
在对similar question 的答复中,有人建议如果您知道样式设置交互将通过标准接口(即始终 使用 jQuery 等)执行,则建议:每当调用库方法时都会触发自定义事件。
这将允许更广泛的支持矩阵,但如果在不使用库方法的情况下执行任何属性更改,则会忽略任何属性更改。似乎这种方法不适用于native setters,因为它们不能总是被依赖。
【讨论】:
【参考方案5】:我发现这个小插件可以做到这一点,并且可以更改它以添加您希望的任何突变...甚至 scrollHeight 更改侦听器。
插件:http://www.jqui.net/jquery-projects/jquery-mutate-official/
这里是演示: http://www.jqui.net/demo/mutate/
【讨论】:
这个插件使用了一种有趣的方法,但它确实使用了轮询(请参阅setTimeout(reset, mutate.speed);
行(您可能需要取消缩小它以使其可读)。【参考方案6】:
您可以使用attrchange jQuery plugin。该插件的主要功能是绑定一个HTML元素属性变化的监听函数。
【讨论】:
这就是 Vega 的回答 (***.com/a/11004907/971299) 实际上插件是因为这个问题而写的!以上是关于在 DOM 元素的样式对象更改后,您可以使用 javascript 钩子触发器吗?的主要内容,如果未能解决你的问题,请参考以下文章
在 CSS 悬停事件中,我可以更改另一个 div 的样式吗? [复制]
chrome扩展跟踪前端JavaScript,该JavaScript使用DOM/jQueryAPI在运行时操作html-DOM元素(例如,更改样式、附加事件侦听器)。