admin管理员组文章数量:1277271
Is there a non-polling method to listen for changes to an element's puted style?
This fantasy code snippet should explain what I mean succinctly:
var el = document.getElementById('doodad');
el.addComputedStyleChangeListener('width', function (prev, new) {
alert('Previous width: ' + prev + '; New width: ' + new);
});
I'm aware of the DOMAttrModified
mutation event and the uping MutationObserver
, but neither is sufficient -- they can only be used to watch the style
DOM attribute of an element, which doesn't wholly determine an element's puted style.
The use case for this was originally part of this question, which really just lead me down a course of curiosity.
Is there a non-polling method to listen for changes to an element's puted style?
This fantasy code snippet should explain what I mean succinctly:
var el = document.getElementById('doodad');
el.addComputedStyleChangeListener('width', function (prev, new) {
alert('Previous width: ' + prev + '; New width: ' + new);
});
I'm aware of the DOMAttrModified
mutation event and the uping MutationObserver
, but neither is sufficient -- they can only be used to watch the style
DOM attribute of an element, which doesn't wholly determine an element's puted style.
The use case for this was originally part of this question, which really just lead me down a course of curiosity.
Share Improve this question edited May 23, 2017 at 12:00 CommunityBot 11 silver badge asked Nov 1, 2012 at 22:23 namuolnamuol 9,9966 gold badges43 silver badges54 bronze badges 9- 6 As far as I know: no. – Matt Ball Commented Nov 1, 2012 at 22:25
- The DOMAttrModified event will be deprecated in DOM 3 Events so not useful anyway (and I think support is pretty patchy to start with). All mutation events will be deprecated, there will be a DOM 4 MutationObserver instead. – RobG Commented Nov 1, 2012 at 23:26
- Agreed with @MattBall, you either trigger an event handler explicitly or use polling – mccannf Commented Nov 2, 2012 at 0:08
- Maybe if you described the goal of doing this people would be able to suggest alternate approaches. – Stephen P Commented Nov 2, 2012 at 0:46
- 3 @namuol - jsfiddle/e5QW5 shows the basic idea. It adds an iframe to the element with a size proportional to the element. When the element size changes, so does the iframe, and the resize event for the iframe's window fires, which can be listened for. – Alohci Commented Nov 2, 2012 at 9:18
3 Answers
Reset to default 3There is no such method. CSS OM is not there yet.
And it is not clear what "puted style change" means.
In principle you can detect change of used (for e.g. rendering) style. But this will need some event like "paint" or "layout" to happen.
A way to achieve this without relying on requestAnimationFrame
is to add a very tight transition duration to the property you want to track and then listen to the transitionstart
event to get the value.
#target {
transition: width 0.001ms step-start;
}
document.getElementById('target').addEventListener('transitionstart', () => {
const styles = getComputedStyle(document.getElementById('target'));
const width = styles.getPropertyValue('width');
console.log(`Width: ${width}`);
});
For discrete properties, don’t forget to include transition-behavior: allow-discrete
in your CSS.
To make things easy, I have abstracted away this approach into an easy to use library named @bramus/style-observer
import CSSStyleObserver from "@bramus/style-observer";
const cssStyleObserver = new CSSStyleObserver(
['width'],
(values) => {
showNotification(values['width']);
}
);
cssStyleObserver.attach(document.getElementById('target'));
The best you can do at the moment is request animation frames.
getComputedStyle
apparently returns a live-updating object of puted properties.
You can do a basic animation loop like this:
var putedStyle = getComputedStyle(element);
var animate = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = putedStyle.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
requestAnimationFrame(animate);
};
animate();
You could potentially optimize by only updating if any of the used properties have changed:
var putedStyle = getComputedStyle(element);
var lastFrameBackground;
var lastFrameColor;
var animate = function () {
if (
putedStyle.background !== lastFrameBackground ||
putedStyle.color !== lastFrameColor
) {
lastFrameBackground = putedStyle.background;
lastFrameColor = putedStyle.color;
// assuming expensive drawing code here
// not like this!
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = putedStyle.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
requestAnimationFrame(animate);
};
animate();
If it's for a specific CSS animation, you could maybe manage the requestAnimationFrame
loop by listening for animationstart
and animationend
, or if those events don't have good enough browser support, you could kick it off when you know the animation will start (e.g. mouseenter
for :hover
) and stop when an animated property's puted value stops changing (i.e. don't call requestAnimationFrame
if it's equal to its previous value).
If you don't need to animate smoothly, you could use setInterval
for possibly-better performance (checking if the document is hidden which requestAnimationFrame
does implicitly):
var putedStyle = getComputedStyle(element);
setInterval(function () {
if (!document.hidden) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = putedStyle.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}, 200);
本文标签: javascriptFire an event when DOM element39s computed style changesStack Overflow
版权声明:本文标题:javascript - Fire an event when DOM element's computed style changes? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741221974a2361132.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论