likes
comments
collection
share

让人混淆的前端属性和属性反射大多数人可能分不清 Property 和 Attributes 的细微区别,虽然我们都认为是

作者站长头像
站长
· 阅读数 52

前言

大多数人可能分不清 Property 和 Attributes 的细微区别,虽然我们都认为是属性,属性反射也是知之甚少,接下来本文将阐述其中区别及用法。

Attributes

Attributes 是在 HTML 中定义的元素上的键值对:

<div id="myDiv" foo="bar"></div>

我们可以通过 js 的api获取属性值,由于 html 是字符,传递的值默认也会转为字符串的形式:

const myDiv = document.getElementById('myDiv');

console.log(myDiv.attributes);
console.log(myDiv.getAttribute('foo'));
console.log(myDiv.hasAttribute('foo'));

这里需要注意如果传入的是 "false",也会是 true:

// 还是禁用状态 disabled
<button disabled="false"></button>

Properties

相比于 attribute,我们可以防止影响dom的重绘,因为 Properties 是基于 js 对象的,我们可以传入复杂的嵌套结构的引用对象,比如数组或者函数等等。

const myDiv = document.getElementById('myDiv');

myDiv.foo = 'bar';

原则

那么什么时候用 Attributes、Properties呢?

  • 使用 JS 时使用 Properties
  • 如果只使用 html 就使用 Attributes
  • 在使用 Attributes 一定要同步属性变化到 js 的Properties (特殊例子:比如你修改了html的checked,但是从js中获取 dom.checked 是无法同步的最新取值的)
  • 不将 Properties 更改同步到相应的 HTML 的Attributes

属性和属性反射

<input type="text" />
console.log(myInput.type); // text
console.log(myInput.getAttribute('type')); // text

如果我们将 type 属性更改为 number ,它将与 property 同步:

myButton.setAttribute('type', 'number');
console.log(myInput.type); // number

但是现在如果我们反着过来,把 js 的 property 修改,那么 html 上的 Attributes 能同步么?

myButton.type = 'date';
console.log(myButton.getAttribute('type')); // date

答案是确实可以,这就是属性反射(Property Reflect),大部分属性都是可以反射到 html 上的。但是也有例外,就是 checked:

<input id="mycheck" type="checkbox" checked />

mycheck.checked = false;
console.log(mycheck.hasAttribute('checked')); // 有问题的 true,应该是false
console.log(mycheck.checked); // false

总结

对于我们平常开发中,我们还是建议从 Attribute 修改更新到 Property,也就是 html 到 js,而不是 js 去更改 html,这是因为自定义的 Property经常更新,每次触发会重绘 DOM 而更影响性能。

转载自:https://juejin.cn/post/7388438687124897846
评论
请登录