gpt4 book ai didi

javascript - 为什么定义 computedStyle 属性的访问器描述符不起作用?

转载 作者:行者123 更新时间:2023-12-01 15:42:08 25 4
gpt4 key购买 nike

我想检测 display 上的值变化class 上的 CSS 属性更改属性,我想出了下面的代码片段。

我知道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");
});
.child {
height: 100px;
background-color: #80a0c0;
}

.hide {
display: none;
}
<button>Toggle</button>
<div class="parent">
<div class="child"></div>
</div>

最佳答案

主机提供的对象不需要玩得很好。 :-) (嗯,有 some requirements 甚至在主机提供的对象上。)

尽管在 Chrome 和相关的对象上声称 display property 是一个简单的数据属性(在 Firefox 和 Legacy Edge 上,它更合理,原型(prototype)上的访问器属性):

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);
.child {
height: 100px;
background-color: #80a0c0;
}

.hide {
display: none;
}
<button>Toggle</button>
<div class="parent">
<div class="child"></div>
</div>


……它在撒谎。 :-)(在 Chrome 上。)您正在成功地在对象上创建访问器属性,然后对象停止反射(reflect)对底层 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);
});
.child {
height: 100px;
background-color: #80a0c0;
}

.hide {
display: none;
}
<button>Toggle</button>
<div class="parent">
<div class="child"></div>
</div>


您可以使用 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);
.as-console-wrapper {
max-height: 100% !important;
}

关于javascript - 为什么定义 computedStyle 属性的访问器描述符不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61836327/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com