未捕获的TypeError:无法设置只有getter

时间:2015-09-08 22:38:15

标签: javascript google-chrome

以下代码在Chrome中失败,Safari在Firefox中正常运行

"use strict";
document.body.style = "background-color: green;";
<p>background should be green</p>

删除“使用严格”,它可以正常工作。

这是Chrome和Safari中的错误还是Firefox中的错误? MDN says setting the style is valid

1 个答案:

答案 0 :(得分:9)

<强>问题

并非所有浏览器都支持将包含CSS声明块的文本表示的字符串分配给style属性。

element.style = styleString; // Might not work

解决方法

作为解决方法,您可以将其设置为内容属性或cssText属性:

element.setAttribute('style', styleString);
element.style.cssText = styleString;

标准行为

在符合DOM L2 Style和ES5的旧浏览器上,分配应该

  • 以严格模式投掷
  • 在非严格模式下被忽略。

在符合CSSOM和ES5的较新浏览器上,分配应该

  • 始终工作

完整详情

根据DOM Level 2 Style规范,style属性在ElementCSSInlineStyle接口中定义如下:

interface ElementCSSInlineStyle {
  readonly attribute CSSStyleDeclaration  style;
};

因此,style属性应该实现为带有getter但没有setter的accessor property

Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'style'); /* {
  configurable: true,
  enumerable: true,
  get: function(){...},
  set: undefined
} */

根据ECMAScript 5,当您尝试为某个属性分配一些值时,必须在严格模式下抛出错误:

  

当在strict mode code内发生作业时,[...]    LeftHandSide 也可能不是具有属性值{[[Set]]: undefined } [...]的访问者属性的引用[...]。在   这些情况会抛出 TypeError 异常。

但是,DOM L2 Style被更新的CSS对象模型(CSSOM)取代。

根据该规范,由HTMLElement实现的接口styleElementCSSInlineStyle IDL属性被定义为[PutForwards]扩展属性:

[NoInterfaceObject]
interface ElementCSSInlineStyle {
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
};

这意味着设置style属性必须像设置CSSStyleDeclaration中的cssText一样。因此,那些必须是等同的:

element.style = styleString;
element.style.cssText = styleString;

这就是为什么它适用于较新的浏览器。