感谢 Günter,我能够使用它来实现一个自定义<ul>
(<ul>
准确地说是一个包装器 Web 组件)MutationObserver
,并且效果很好。
如果有人感兴趣,我制作了一个示例项目,演示了我如何使用MutationObserver
Polymer.dart。
https://github.com/rillomas/custom-list
在示例中,我使用MutationObserver
如下:
@override
void enteredView() {
super.enteredView();
_root = shadowRoot.querySelector("#root");
// observe change of child elements for a 2 pass layout approach
var mo = new MutationObserver(onChildMutation);
mo.observe(_root, childList:true);
_observer = mo;
}
/// Called when a mutation occurs to the target element
void onChildMutation(List<MutationRecord> changes, MutationObserver observer) {
// layout children depending on its rendering size
int itemCount = 0;
int bounceBackDelta = bouncebacknum - 1;
int nextBounceBack = bounceBackDelta;
int xOffset = 0;
int yOffset = 0;
bool offsetRight = true;
for (var record in changes) {
var added = record.addedNodes;
var removed = record.removedNodes;
for (var a in added) {
if (!(a.nodeType == Node.ELEMENT_NODE && a is CustomListItem)) {
// ignore nodes expect for the one we want
continue;
}
var elem = a as CustomListItem;
var width = elem.clientWidth;
var height = elem.clientHeight;
// print("${width}x${height}");
var unit = "px";
if (elem.item.entered) {
// This item is already displayed
// so place the view at the same position
var l = "${elem.item.rect.left}${unit}";
var t = "${elem.item.rect.top}${unit}";
elem.style.left = l;
elem.style.top = t;
} else {
// This item is a new one.
// Layout the remark at a sufficient position
Rectangle<int> posRect;
if (offsetRight) {
posRect = new Rectangle<int>(xOffset,yOffset,width, height);
} else {
posRect = new Rectangle<int>(xOffset-width, yOffset, width, height);
}
var l = "${posRect.left}${unit}";
var t = "${posRect.top}${unit}";
elem.style.left = l;
elem.style.top = t;
elem.item.rect = posRect;
applyAnimation(elem, "fadein", 250);
elem.item.entered = true;
}
// update offset depending on direction
if (offsetRight) {
xOffset += width;
} else {
xOffset -= width;
}
// update bounceback state
if (offsetRight && itemCount == nextBounceBack) {
offsetRight = false;
xOffset -= width;
nextBounceBack += bounceBackDelta;
} else if (!offsetRight && itemCount == nextBounceBack) {
offsetRight = true;
xOffset += width;
nextBounceBack += bounceBackDelta;
}
yOffset += height;
itemCount++;
}
}
}