是否有非民意方法来监听元素computed style的更改?
这个幻想代码片段应该简洁地解释我的意思:
var el = document.getElementById('doodad');
el.addComputedStyleChangeListener('width', function (prev, new) {
alert('Previous width: ' + prev + '; New width: ' + new);
});
我知道DOMAttrModified
突变事件和即将发生的MutationObserver
,但两者都不够 - 它们只能用于观察元素的style
DOM属性,它并不完全确定元素的计算样式。
用于此的用例最初是this question的一部分,这真的只会引起我的好奇心。
答案 0 :(得分:4)
没有这样的方法。 CSS OM还没有。
目前尚不清楚"计算出的风格变化"装置
原则上,您可以检测已使用(例如渲染)样式的更改。但这需要 像" paint"或"布局"即将发生。
答案 1 :(得分:0)
目前你能做的最好的就是请求动画帧。
getComputedStyle
显然会返回计算属性的实时更新对象。
你可以像这样做一个基本的动画循环:
var computedStyle = getComputedStyle(element);
var animate = function () {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = computedStyle.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
requestAnimationFrame(animate);
};
animate();
如果任何已使用的属性发生更改,您可以通过仅更新进行优化:
var computedStyle = getComputedStyle(element);
var lastFrameBackground;
var lastFrameColor;
var animate = function () {
if (
computedStyle.background !== lastFrameBackground ||
computedStyle.color !== lastFrameColor
) {
lastFrameBackground = computedStyle.background;
lastFrameColor = computedStyle.color;
// assuming expensive drawing code here
// not like this!
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = computedStyle.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
requestAnimationFrame(animate);
};
animate();
如果是针对特定的CSS动画,您可以通过聆听requestAnimationFrame
和animationstart
来管理animationend
循环,或者如果这些事件不合适有足够的浏览器支持,你可以在你知道动画开始时(例如mouseenter
为:hover
)启动它,并在动画属性的计算值停止变化时停止(即不要&# 39;如果requestAnimationFrame
等于之前的值,则调用setInterval
。
如果您不需要动画制作动画,可以使用requestAnimationFrame
获得更好的效果(检查文档是否隐藏var computedStyle = getComputedStyle(element);
setInterval(function () {
if (!document.hidden) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = computedStyle.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}, 200);
隐式执行的操作:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Grid1 g = myCanvas.CreateGrid();
ContentControl1 cc = myCanvas.CreateCC();
Button1 b = myCanvas.CreateButton1();
Grid1.SetColumn(cc, 0);
Grid1.SetRow(cc, 0);
Grid1.SetColumn(b, 1);
Grid1.SetRow(b, 1);
g.Children.Add(cc);
g.Children.Add(b);
Canvas1.SetLeft(g, 500);
Canvas1.SetTop(g, 5);
myCanvas.Children.Add(g);
}
}
public class Button1 : Button
{
protected override void OnClick()
{
Grid1 old_g = (Grid1)VisualTreeHelper.GetParent(this as DependencyObject);
Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(old_g as DependencyObject);
Grid1 g = cnv.CreateGrid();
ContentControl1 cc = cnv.CreateCC();
Button1 b = cnv.CreateButton1();
Grid1.SetColumn(cc, 0);
Grid1.SetRow(cc, 0);
Grid1.SetColumn(b, 1);
Grid1.SetRow(b, 1);
g.Children.Add(cc);
g.Children.Add(b);
Canvas1.SetLeft(g, 500);
Canvas1.SetTop(g, cnv.Children.Count * 120);
cnv.Children.Add(g);
cnv.ConnectGrids(old_g, g);
}
}
public class Canvas1 : Canvas
{
public Grid1 CreateGrid()
{
Grid1 g = new Grid1() { Width = 100, Height = 20, Background = Brushes.White };
g.HorizontalAlignment = HorizontalAlignment.Center;
g.VerticalAlignment = VerticalAlignment.Center;
g.ShowGridLines = false;
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition() { Width = new GridLength(20) };
g.ColumnDefinitions.Add(colDef1);
g.ColumnDefinitions.Add(colDef2);
RowDefinition rowDef1 = new RowDefinition();
g.RowDefinitions.Add(rowDef1);
return g;
}
public ContentControl1 CreateCC()
{
ContentControl1 cc = new ContentControl1()
{
VerticalContentAlignment = VerticalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
BorderBrush = Brushes.BlueViolet,
};
return cc;
}
public Button1 CreateButton1()
{
Button1 b = new Button1()
{
VerticalContentAlignment = VerticalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Stretch,
BorderBrush = Brushes.Red
};
return b;
}
public void ConnectGrids(Grid1 g1, Grid1 g2)
{
Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(g1 as DependencyObject);
Transform transform1 = (Transform)g1.TransformToVisual(cnv as Visual);
Transform transform2 = (Transform)g2.TransformToVisual(cnv as Visual);
Point StartPoint1 = transform1.Transform(new Point(g1.Width, g1.Height / 2.0));
Point EndPoint1 = transform2.Transform(new Point(g2.Width, g2.Height / 2.0));
var lineGeometry = new LineGeometry()
{
StartPoint = StartPoint1,
EndPoint = EndPoint1
};
var path = new Path()
{
Data = lineGeometry,
Stroke = new SolidColorBrush(Colors.Black),
};
cnv.Children.Add(path);
}
}
public class ContentControl1 : ContentControl
{
}
public class Grid1 : Grid
{
}
}