首先,这个问题有很多重复,但这些答案并没有给出更深入的见解。
Q1。为什么会导致200,0?
请考虑以下代码段:
var el = document.querySelector('#r');
console.log('First:: ' + el.offsetHeight);
el.style = {
height: el.offsetHeight + 500 + 'px'
}
console.log('Second:: ' + el.offsetHeight);

<div id="r" style="height:200px;width:800px;overflow:auto;border:1px solid;margin:20px;box-sizing:border-box"></div>
&#13;
我怀疑el.style
是只读的,所以我希望设置一个对象应该静默失败,因此我希望输出为
First:: 200,Second:: 200
但它是:
First:: 200,Second:: 0
为什么?
Q2。为什么使用Object.assign设置el.style有效?
Object.assign(el.style,{
height : el.offsetHeight + 500
})
有人可以用更深入的见解向我解释一下吗?
答案 0 :(得分:1)
关于您的第一个问题:
MDN表示尽管style
对象是只读的,但FF,Chrome和Opera确实允许对其进行分配(https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style)。现在,offsetHeight
属性是只读的(https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight),因此尝试设置style
会导致该属性重置为零,因为offsetHeight
是计算值,而不是显式设置的值,并且您的浏览器实际上允许设置样式属性(尽管不正确)。
关于第二个问题:
Object.assign
工作的原因直接写入Object.assign的文档中。 它不会替换该对象,它会替换该对象的可枚举属性。来自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
&#34;目标对象中的属性将被属性覆盖 如果他们有相同的密钥来源。后来的消息来源&#39;属性会 类似地覆盖了之前的那些。
Object.assign()方法仅复制可枚举和自己的属性 从源对象到目标对象。&#34;
所以,在你的第一次尝试中:
el.style = {
height: el.offsetHeight + 500 + 'px'
}
您正在尝试替换失败的整个对象,但Object.assign只会复制属性,这会成功。
答案 1 :(得分:1)
问题在于这句话:
el.style = {
height: el.offsetHeight + 500 + 'px'
};
这不仅不起作用(例如,元素的CSS height
不设置为700px
),但它也删除以前在元素上设置的所有内联样式(style
属性):
由于您的<div>
完全为空,其高度将为零。这就是el.offsetHeight
最后返回0
的原因。
答案 2 :(得分:0)
基于Chrome https://chromium.googlesource.com/chromium/src/+/d1a7b0cbd0a511459f0f6202dfe61e27aa47df46。,
当我们设置任何属性时,它会将其转发到el.style.cssText
(请参阅规范https://drafts.csswg.org/cssom/#the-cssstylerule-interface)
它表示 [PutForwards = cssText]
所以在分配字符串时,
el.style = 'some valid css string';
// it takes the string and assigns to cssText
el.style.cssText = 'some valid css string';
// So when assigning an object
el.style = {...};
// it takes the object and converts to string toString()
el.style.cssText = '[object Object]';
// Since it is not valid , it unsets everything
答案 3 :(得分:0)
我进行了查找,因为我有一系列要更改的样式属性,想知道是否可以使用一个对象来使它看起来更整洁。 如果有人想知道并且会偶然发现这个主题,这就是我想出的:
var setStyle = {
zIndex: 10000,
position: "absolute",
top: somey,
left: somex,
opacity: 1,
height: someh + "px",
width: somew + "px"
}
for(prop of Object.keys(setStyle)){
elem.style[prop.toString()] = setStyle[prop.toString()];
}
保重