innerHTML和

时间:2017-12-10 09:41:59

标签: javascript html

我有一个奇怪的JavaScript行为,我无法解释。

考虑以下代码:

var el = document.createElement('div')
var s = String.fromCharCode(160)

el.innerHTML = s

console.log(s)            // prints space
console.log(el.innerHTML) // prints " "

现在我知道 是不间断的空间,但从技术上讲,我只是将一个变量赋值给另一个变量,两者都是字符串。 为什么价值观不同?

innerHTML是一种特殊的字符串还是什么?

它是如何工作的?翻译这个的机制是什么?

2 个答案:

答案 0 :(得分:10)

  

从技术上讲,我只是将一个变量赋值给另一个变量,两者都是字符串。为什么价值观不同?

因为是的,innerHTML很特别。它不仅仅是一个简单的值属性,它还是一个 accessor 属性。当你分配给它时,你正在调用一个函数,它解析你给它的HTML并创建必要的DOM节点和元素。当你读取它的值时,你正在调用另一个函数,它从你访问它的元素开始遍历DOM树,并构建一个表示该DOM树的HTML字符串。

所以当你为它分配字符U + 00A0时,它变成了一个DOM文本节点;当你从中读取时,该DOM文本节点被渲染为规范(根据浏览器的规则)HTML字符串: 

通过使用DOM来操作元素,您可以看到innerHTML不仅仅是一个简单的值属性:

var target = document.getElementById("target");
target.innerHTML = "\u00A0";
console.log(target.innerHTML); // " "
target.appendChild(
  document.createElement("span")
);
console.log(target.innerHTML); // "&nbsp;<span></span>"
<div id="target"></div>

请注意,也可以在JavaScript对象中定义访问者属性;它不只是可以拥有它们的DOM:

var o = {
  get foo() {
    console.log("foo getter called");
    return this._foo;
  },
  set foo(value) {
    console.log("foo setter called");
    this._foo = value;
  }
};
console.log("foo: " + o.foo);
o.foo = 42;
console.log("foo: " + o.foo);

事件innerHTML是一个带有getter和setter的属性,这就是为什么这样的代码很糟糕的原因:

for (var n = 0; n < something.length; ++n) {
    element.innerHTML += ", " + something[n];
}

这是不断构建然后销毁和重建DOM树并进行隐藏函数调用的。相反,你要构建字符串,然后分配它。

答案 1 :(得分:3)

innerHTML不是一个简单的属性,它是一个带有gettersetter访问者属性。意味着引擎盖下的功能。 innerHTML将给定输入序列化为HTML。它解析给定的值,创建元素和节点,然后将这些元素附加到元素。

它定义如下

const DOMElement = {
  value: null,
  set innerHTML(html) {
     console.log(`Setting html: ${html}`);
     // Translate into elements and nodes, then append to the element
     this.value = html;
  },
  get innerHTML() {
     console.log(`Getting html:`);
     // Translate into string, then return it
     return this.value;
  }
};

DOMElement.innerHTML = '<p>Hello</p>';
console.log(DOMElement.innerHTML);

如果要在不进行序列化的情况下打印给定字符,可以使用textContent属性。