最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why do strings obtained from the innerHTML property not come out exactly as they were assigned before? - Stack Over

programmeradmin8浏览0评论

I have a weird JavaScript behavior which I cannot explain.

Consider this code:

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

el.innerHTML = s

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

Now I know that   is non-breaking space, but technically, I just made an assignment of one variable to another, both are strings. How e the values are different?

Is innerHTML a special kind of string or something?

How does it work? What Is the mechanism which translates this?

I have a weird JavaScript behavior which I cannot explain.

Consider this code:

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

el.innerHTML = s

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

Now I know that   is non-breaking space, but technically, I just made an assignment of one variable to another, both are strings. How e the values are different?

Is innerHTML a special kind of string or something?

How does it work? What Is the mechanism which translates this?

Share Improve this question edited Dec 4, 2024 at 17:58 dumbass 27.2k4 gold badges36 silver badges73 bronze badges asked Dec 10, 2017 at 9:41 Yossi VainshteinYossi Vainshtein 3,9855 gold badges26 silver badges43 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 13

technically, I just made an assignment of one variable to another, both are strings. How e the values are different?

Because yes, innerHTML is special. It's not just a simple value property, it's an accessor property. When you assign to it, you're calling a function under-the-covers which parses the HTML you give it and creates the necessary DOM nodes and elements. When you read its value, you're calling another function under-the-covers which recurses through the DOM tree starting from the element on which you access it and builds an HTML string representing that DOM tree.

So while you assigned the character U+00A0 to it, that got turned into a DOM text node; and when you read from it, that DOM text node was rendered as a canonical (per that browser's rules) HTML string:  .

You can see that innerHTML isn't just a simple value property by using the DOM to manipulate the element:

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>

Note that it's possible to define accessor properties in JavaScript objects as well; it's not just the DOM that can have them:

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);

The fact that innerHTML is a property with a getter and setter is why code like this is poor practice:

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

That's constantly building and then destroying and rebuilding a DOM tree and making a bunch of hidden function calls. Instead, you'd build the string, then assign it.

innerHTML is not a simple property, it's an accessor property with getter and setter. Means that under the hood functions work. innerHTML serializes the given input into HTML. It parses the given value, creates elements and nodes, then appends those ones to the element.

It is defined like this

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);

If you want to print the given character without serializing, you can use textContent property.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论