我想通过display属性的变化来检测CSS 属性的值变化class,我想出了下面的代码片段。
我知道getComputedStyle返回一个只读的活动CSSStyleDeclaration对象,但是当元素的样式改变时对象会自动更新,我假设它以某种方式分配了它的属性。
但它没有调用 getter 和 setter。为什么会发生这种情况,然后它在只读时如何分配其属性?
let parent = document.querySelector(".parent");
let child = parent.querySelector(".child");
let style = getComputedStyle(child);
let display = Symbol("display");
style[display] = style.display;
Object.defineProperty(style, "display", {
get() {
console.log("getter");
return style[display];
},
set(value) {
console.log("setter", value);
style[display] = value;
}
});
let button = document.querySelector("button");
button.addEventListener("click", () => {
child.classList.toggle("hide");
});Run Code Online (Sandbox Code Playgroud)
.child {
height: 100px;
background-color: #80a0c0;
}
.hide {
display: none;
}Run Code Online (Sandbox Code Playgroud)
<button>Toggle</button>
<div class="parent">
<div class="child"></div>
</div>Run Code Online (Sandbox Code Playgroud)
主机提供的对象不需要玩得很好。:-)(嗯,即使是主机提供的对象也有一些要求。)
尽管在 Chrome 和相关对象上,该对象声称该display属性是一个简单的数据属性(在 Firefox 和 Legacy Edge 上,它更合理,是原型上的访问器属性):
let style = getComputedStyle(document.querySelector(".child"));
let kind = "own";
do {
const descr = Object.getOwnPropertyDescriptor(style, "display");
if (descr) {
console.log(kind + " property:", descr);
break;
}
if (kind === "own") {
kind = "prototype";
} else {
kind += "'s prototype";
}
style = Object.getPrototypeOf(style);
} while (style);Run Code Online (Sandbox Code Playgroud)
.child {
height: 100px;
background-color: #80a0c0;
}
.hide {
display: none;
}Run Code Online (Sandbox Code Playgroud)
<button>Toggle</button>
<div class="parent">
<div class="child"></div>
</div>Run Code Online (Sandbox Code Playgroud)
……这是说谎。:-)(在 Chrome 上。)您成功地在对象上创建了一个访问器属性,然后该对象停止反映对该display元素的基础属性的更改(因为它只是更新您用符号命名的属性):
let parent = document.querySelector(".parent");
let child = parent.querySelector(".child");
let style = getComputedStyle(child);
let display = Symbol("display");
style[display] = style.display;
Object.defineProperty(style, "display", {
get() {
console.log("getter");
return style[display];
},
set(value) {
console.log("setter", value);
style[display] = value;
}
});
let button = document.querySelector("button");
button.addEventListener("click", () => {
child.classList.toggle("hide");
console.log("style.display: " + style.display);
});Run Code Online (Sandbox Code Playgroud)
.child {
height: 100px;
background-color: #80a0c0;
}
.hide {
display: none;
}Run Code Online (Sandbox Code Playgroud)
<button>Toggle</button>
<div class="parent">
<div class="child"></div>
</div>Run Code Online (Sandbox Code Playgroud)
您可以使用以下命令复制相同的行为Proxy:
const realStyle = {
display: "block"
};
const style = new Proxy(realStyle, {
get(target, propName) {
return target[propName];
},
set(target, propName, value, receiver) {
if (propName in target) {
return;
}
return Reflect.set(target, propName, value, receiver);
}
});
console.log("descriptor for `display`:");
console.log(Object.getOwnPropertyDescriptor(style, "display"));
console.log("style.display = " + style.display);
console.log("Setting it to 'none'");
style.display = "none";
console.log("style.display = " + style.display);
const d = Symbol("display");
style[d] = style.display;
Object.defineProperty(style, "display", {
get() {
console.log("getter");
return style[d];
},
set(value) {
console.log("setter");
style[d] = value;
}
});
console.log("style.display = " + style.display);
console.log("Setting it to 'none'");
style.display = "none";
console.log("style.display = " + style.display);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper {
max-height: 100% !important;
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |