使用JavaScript对象更改element.style

时间:2016-11-04 15:50:51

标签: javascript html css dom

首先,这个问题有很多重复,但这些答案并没有给出更深入的见解。

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;
&#13;
&#13;

我怀疑el.style是只读的,所以我希望设置一个对象应该静默失败,因此我希望输出为

First:: 200,Second:: 200

但它是:

First:: 200,Second:: 0

为什么?

Q2。为什么使用Object.assign设置el.style有效?

Object.assign(el.style,{
   height : el.offsetHeight + 500 
})

有人可以用更深入的见解向我解释一下吗?

4 个答案:

答案 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属性):

enter image description here

由于您的<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()];
  }

保重