是否已经开发了使用setAttribute代替点(.)属性表示法的最佳实践?

例如:

myObj.setAttribute("className", "nameOfClass");
myObj.setAttribute("id", "someID");

or

myObj.className = "nameOfClass";
myObj.id = "someID";

当前回答

这是很好的讨论。我曾有过这样的时刻,我希望,或者让我说希望(我可以补充说,是成功的)重新发明轮子,不管它是正方形的。 上面的任何方法都是很好的讨论,所以任何来这里寻找Element属性和属性之间的区别的人。这是我最值钱的一分钱,我的确是费了好大劲才发现的。我会保持简单,所以没有特别的技术术语。

假设我们有一个变量a。我们所习惯的如下。

下面会抛出一个错误,因为它简单地写了它是一种只能有一个属性的对象,即单数左手边对象=单数右手边对象。其他的东西都被忽略,扔进垃圾桶。 let A = 'f'; A.b = 2; console.log (A.b);

谁决定它必须是单数=单数。那些制定JavaScript和html标准的人,这就是引擎工作的方式。

让我们换个例子。

let A = {}; A.b = 2; console.log (A.b);

这一次它工作.....因为我们已经明确地告诉它了,谁决定我们可以在这个例子中告诉它,而不是在以前的例子中。还是那些制定JavaScript和html标准的人。

我希望我们在这个问题上,让它进一步复杂化

let A = {}; A.attribute = {}; A.attribute.b = 5; console.log (A.attribute.b);//将工作 console.log (A.b);//将不起作用

我们所做的是第一层的树和非奇异对象的子层。除非你知道什么是哪里,并调用它,否则它将工作。

这就是HTMLDOM在为每个HTML元素创建解析和绘制DOm树时所发生的事情。每个都有不同级别的属性。有些是预定义的,有些不是。这就是ID和VALUE位发挥作用的地方。 在场景后面,它们在1级属性和sun级属性(属性)之间以1:1的比例映射。因此,改变一个就会改变另一个。这就是对象getter和setter方案的作用。

let A = { attribute :{ id:'', value:'' }, getAttributes: function (n) { return this.attribute[n]; }, setAttributes: function (n,nn){ this.attribute[n] = nn; if(this[n]) this[n] = nn; }, id:'', value:'' }; A.id = 5; console.log(A.id); console.log(A.getAttributes('id')); A.setAttributes('id',7) console.log(A.id); console.log(A.getAttributes('id')); A.setAttributes('ids',7) console.log(A.ids); console.log(A.getAttributes('ids')); A.idsss=7; console.log(A.idsss); console.log(A.getAttributes('idsss'));

如上所示,ELEMENTS有另一组所谓的属性列表属性,它有自己的主要属性。在两者之间有一些预定义的属性,并以1:1的比例映射,例如ID对每个人都是公共的,但value不是,src也不是。当解析器到达这一点时,它只是简单地调出字典,以确定何时出现这样那样的东西。

所有元素都有属性和属性,它们之间的一些项是公共的。在一个国家常见的东西在另一个国家并不常见。

在过去的HTML3时代,我们首先使用html,然后使用JS。现在的日子,它的其他方式,所以已经使用内联onclick成为如此令人憎恶。在HTML5中,有许多属性列表可以作为集合访问,例如类,样式。在过去,颜色是一个属性,现在被移动到css处理不再有效的属性。

元素。attributes是元素属性中的子属性列表。

除非你能改变Element属性的getter和setter,这几乎是不可能的,因为它会破坏所有的功能,通常是不能立即写出来的,只是因为我们定义了一个A.item并不一定意味着Js引擎也会运行另一行函数将它添加到Element.attributes.item中。

我希望这能进一步澄清什么是什么。 为了这个目的,我尝试了element。prototype。setattribute和自定义函数,它只是打破了所有的东西,因为它覆盖了本地的一堆函数,设置属性函数在幕后发挥作用。

其他回答

“在JavaScript中什么时候使用setAttribute vs .attribute= ?”

一般的规则是使用.attribute并检查它是否在浏览器上工作。

..如果它可以在浏览器上运行,那么就可以开始了。

..如果没有,使用. setattribute (attribute, value)来代替该属性的.attribute。

冲洗-重复所有属性。

如果你很懒,你可以简单地使用. setattribute。这在大多数浏览器上都可以正常工作。(尽管支持.attribute的浏览器可以比. setattribute (attribute, value)更好地优化它。)

来自Javascript: The Definitive Guide,它澄清了一些事情。它注意到HTML文档的HTMLElement对象定义了与所有标准HTML属性对应的JS属性。

因此,您只需要对非标准属性使用setAttribute。

例子:

node.className = 'test'; // works
node.frameborder = '0'; // doesn't work - non standard attribute
node.setAttribute('frameborder', '0'); // works

如果您希望在JavaScript中进行编程访问,您应该始终使用直接的.attribute形式(但请参阅下面的quirksmode链接)。它应该正确地处理不同类型的属性(想想“onload”)。

使用getAttribute/setAttribute当你希望处理DOM,因为它是(例如,文字文本)。不同的浏览器会混淆这两者。参见怪癖模式:属性(在)兼容性。

这些答案并没有真正解决属性和属性之间的巨大混淆。此外,根据Javascript原型,有时可以使用元素的属性访问属性,有时不能。

首先,您必须记住HTMLElement是一个Javascript对象。像所有对象一样,它们也有属性。当然,您可以在HTMLElement中创建几乎任何名称的属性,但它不需要与DOM(页面上的内容)做任何事情。点符号(.)用于属性。现在,有一些特殊的属性被映射到属性,在编写时,只有4个属性是有保证的(稍后会详细介绍)。

All HTMLElements include a property called attributes. HTMLElement.attributes is a live NamedNodeMap Object that relates to the elements in the DOM. "Live" means that when the node changes in the DOM, they change on the JavaScript side, and vice versa. DOM attributes, in this case, are the nodes in question. A Node has a .nodeValue property that you can change. NamedNodeMap objects have a function called setNamedItem where you can change the entire node. You can also directly access the node by the key. For example, you can say .attributes["dir"] which is the same as .attributes.getNamedItem('dir'); (Side note, NamedNodeMap is case-insensitive, so you can also pass 'DIR');

在HTMLElement中有一个类似的函数,你可以直接调用setAttribute,如果它不存在,它会自动创建一个节点并设置nodeValue。还有一些属性你可以通过特殊的属性直接访问HTMLElement中的属性,比如dir。以下是它的大致外观:

HTMLElement {
  attributes: {
    setNamedItem: function(attr, newAttr) { 
      this[attr] = newAttr;
    },    
    getNamedItem: function(attr) {
      return this[attr];
    },
    myAttribute1: {
      nodeName: 'myAttribute1',
      nodeValue: 'myNodeValue1'
    },
    myAttribute2: {
      nodeName: 'myAttribute2',
      nodeValue: 'myNodeValue2'
    },
  }
  setAttribute: function(attr, value) { 
    let item = this.attributes.getNamedItem(attr);
    if (!item) {
      item = document.createAttribute(attr);
      this.attributes.setNamedItem(attr, item);
    }
    item.nodeValue = value;
  },
  getAttribute: function(attr) { 
    return this.attributes[attr] && this.attributes[attr].nodeValue;
  },
  dir: // Special map to attributes.dir.nodeValue || ''
  id:  // Special map to attributes.id.nodeValue || ''
  className: // Special map to attributes.class.nodeValue || '' 
  lang: // Special map to attributes.lang.nodeValue || ''

}

所以你可以用6种方法改变dir属性:

  // 1. Replace the node with setNamedItem
  const newAttribute = document.createAttribute('dir');
  newAttribute.nodeValue = 'rtl';
  element.attributes.setNamedItem(newAttribute);

  // 2. Replace the node by property name;
  const newAttribute2 = document.createAttribute('dir');
  newAttribute2.nodeValue = 'rtl';
  element.attributes['dir'] = newAttribute2;
  // OR
  element.attributes.dir = newAttribute2;

  // 3. Access node with getNamedItem and update nodeValue
  // Attribute must already exist!!!
  element.attributes.getNamedItem('dir').nodeValue = 'rtl';

  // 4. Access node by property update nodeValue
  // Attribute must already exist!!!
  element.attributes['dir'].nodeValue = 'rtl';
  // OR
  element.attributes.dir.nodeValue = 'rtl';

  // 5. use setAttribute()  
  element.setAttribute('dir', 'rtl');
  
  // 6. use the UNIQUELY SPECIAL dir property
  element["dir"] = 'rtl';
  element.dir = 'rtl';

您可以使用方法#1-5更新所有属性,但只能使用方法#6更新dir、id、lang和className。

HTMLElement的扩展

HTMLElement has those 4 special properties. Some elements are extended classes of HTMLElement have even more mapped properties. For example, HTMLAnchorElement has HTMLAnchorElement.href, HTMLAnchorElement.rel, and HTMLAnchorElement.target. But, beware, if you set those properties on elements that do not have those special properties (like on a HTMLTableElement) then the attributes aren't changed and they are just, normal custom properties. To better understand, here's an example of its inheritance:

HTMLAnchorElement extends HTMLElement {
  // inherits all of HTMLElement
  href:    // Special map to attributes.href.nodeValue || ''
  target:  // Special map to attributes.target.nodeValue || ''
  rel:     // Special map to attributes.ref.nodeValue || '' 
}

自定义属性

现在要警告的是:像所有Javascript对象一样,您可以添加自定义属性。但是,这些不会改变DOM上的任何东西。你可以:

  const newElement = document.createElement('div');
  // THIS WILL NOT CHANGE THE ATTRIBUTE
  newElement.display = 'block';

但这和

  newElement.myCustomDisplayAttribute = 'block';

这意味着添加自定义属性将不会链接到.attributes[attr]. nodevalue。

性能

我已经构建了一个jsperf测试用例来显示区别:https://jsperf.com/set-attribute-comparison。基本上,依次为:

自定义属性,因为它们不影响DOM,也不是属性。 浏览器提供的特殊映射(dir, id, className)。 如果属性已经存在,则element.attributes.ATTRIBUTENAME.nodeValue = setAttribute (); 如果属性已经存在,则element.attributes.getNamedItem(ATTRIBUTENAME)。nodeValue = newValue element.attributes.ATTRIBUTENAME = newNode element.attributes.setNamedItem(ATTRIBUTENAME) = newNode

结论(TL;博士)

使用来自HTMLElement: element的特殊属性映射。dir,元素。id元素。className或element.lang。 如果您100%确定该元素是具有特殊属性的扩展HTMLElement,则使用该特殊映射。你可以用if (element instanceof htmllanchorelement)来检查。 如果您100%确定属性已经存在,则使用element.attributes.ATTRIBUTENAME.nodeValue = newValue。 如果不是,使用setAttribute()。

这看起来像是使用setAttribute更好的一种情况:

高效的JavaScript

var posElem = document.getElementById('animation');
var newStyle = 'background: ' + newBack + ';' +
'color: ' + newColor + ';' +
    'border: ' + newBorder + ';';
if(typeof(posElem.style.cssText) != 'undefined') {
    posElem.style.cssText = newStyle;
} else {
    posElem.setAttribute('style', newStyle);
}