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

例如:

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

or

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

当前回答

If the element you are referring to does not already include a Javascript object property for a given attribute (as others have described), then setting that property will not propagate the change back to the DOM, it just adds the named property to the Javascript object, and the DOM ignores it. For example, getting the element mySpan by id and then doing mySpan.class = 'warning' will do nothing, whether or not the span element in question already has a class attribute defined, because mySpan.class is not defined in the Javascript object for a span element. You have to use mySpan.setAttribute('class', 'warning').

然而,第二个细微差别是使用mySpan设置Javascript对象的innerHTML属性。setAttribute("innerHTML", someHTML)不会更新元素的内容。我不知道Javascript是如何捕获mySpan的。innerHTML = something,并调用HTML解析器,但在底层有一些神奇的东西。

其他回答

这看起来像是使用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);
}

来自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

我发现需要使用setAttribute的一种情况是在更改ARIA属性时,因为没有相应的属性。例如

x.setAttribute('aria-label', 'Test');
x.getAttribute('aria-label');

没有x。arialabel之类的东西,所以你必须使用setAttribute。

编辑:x["aria-label"]不工作。你确实需要setAttribute。

x.getAttribute('aria-label')
null
x["aria-label"] = "Test"
"Test"
x.getAttribute('aria-label')
null
x.setAttribute('aria-label', 'Test2')
undefined
x["aria-label"]
"Test"
x.getAttribute('aria-label')
"Test2"

之前的答案都不完整,大多数都包含错误信息。

在JavaScript中有三种访问DOM元素属性的方法。这三种方法都可以在现代浏览器中可靠地工作,只要您了解如何使用它们。

1. element.attributes

元素有一个属性属性,它返回Attr对象的活动NamedNodeMap。此集合的索引可能因浏览器而异。所以,顺序是不能保证的。NamedNodeMap有添加和删除属性的方法(分别是getNamedItem和setNamedItem)。

注意,尽管XML显式区分大小写,但DOM规范要求规范化字符串名称,因此传递给getNamedItem的名称实际上是不区分大小写的。

使用示例:

var div = document.getElementsByTagName('div')[0]; //you can look up specific attributes var classAttr = div.attributes.getNamedItem('CLASS'); document.write('attributes.getNamedItem() Name: ' + classAttr.name + ' Value: ' + classAttr.value + '<br>'); //you can enumerate all defined attributes for(var i = 0; i < div.attributes.length; i++) { var attr = div.attributes[i]; document.write('attributes[] Name: ' + attr.name + ' Value: ' + attr.value + '<br>'); } //create custom attribute var customAttr = document.createAttribute('customTest'); customAttr.value = '567'; div.attributes.setNamedItem(customAttr); //retreive custom attribute customAttr = div.attributes.getNamedItem('customTest'); document.write('attributes.getNamedItem() Name: ' + customAttr.name + ' Value: ' + customAttr.value + '<br>'); <div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

2. element.getAttribute & element.setAttribute

这些方法直接存在于Element上,不需要访问属性及其方法,但执行相同的功能。

再次注意,字符串名称是不区分大小写的。

使用示例:

var div = document.getElementsByTagName('div')[0]; //get specific attributes document.write('Name: class Value: ' + div.getAttribute('class') + '<br>'); document.write('Name: ID Value: ' + div.getAttribute('ID') + '<br>'); document.write('Name: DATA-TEST Value: ' + div.getAttribute('DATA-TEST') + '<br>'); document.write('Name: nonStandard Value: ' + div.getAttribute('nonStandard') + '<br>'); //create custom attribute div.setAttribute('customTest', '567'); //retreive custom attribute document.write('Name: customTest Value: ' + div.getAttribute('customTest') + '<br>'); <div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

3.DOM对象上的属性,例如element.id

使用DOM对象上的方便属性可以访问许多属性。给定对象上存在哪些属性取决于对象的DOM节点类型,而与HTML中指定的属性无关。可用的属性定义在DOM对象原型链中的某个地方。因此,所定义的特定属性将取决于您正在访问的Element的类型。

例如,className和id定义在Element上,存在于所有DOM节点上,这些节点是元素,但不包括文本或注释节点。价值的定义更为狭义。它只在HTMLInputElement和它的后代上可用。

注意,JavaScript属性是区分大小写的。尽管大多数属性将使用小写字母,但也有一些是驼峰式的。所以一定要检查说明书。

这个“图表”捕获了这些DOM对象的原型链的一部分。它甚至还没有完成,但它展示了整体结构。

                      ____________Node___________
                      |               |         |
                   Element           Text   Comment
                   |     |
           HTMLElement   SVGElement
           |         |
HTMLInputElement   HTMLSpanElement

使用示例:

var div = document.getElementsByTagName('div')[0]; //get specific attributes document.write('Name: class Value: ' + div.className + '<br>'); document.write('Name: id Value: ' + div.id + '<br>'); document.write('Name: ID Value: ' + div.ID + '<br>'); //undefined document.write('Name: data-test Value: ' + div.dataset.test + '<br>'); //.dataset is a special case document.write('Name: nonStandard Value: ' + div.nonStandard + '<br>'); //undefined <div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

注意:本文解释了HTML规范如何定义属性,以及现代的常青浏览器如何处理属性。当然,有些老的浏览器(IE、Netscape等)没有遵守这个规范,甚至比这个规范更早。如果你需要支持旧的(破损的)浏览器,你需要的信息比这里提供的更多。

谷歌API脚本对此进行了有趣的观察:

他们是这样做的:

var scriptElement = document.createElement("script");
scriptElement = setAttribute("src", "https://some.com");
scriptElement = setAttribute("nonce", "https://some.com");
scriptElement.async = "true";

注意,他们如何为"src"和"nonce"使用setAttribute,但是。async =…对于“async”属性。

我不是100%确定,但可能是因为“async”只在支持直接。attr =赋值的浏览器上被支持。因此,尝试setAttribute("async")是没有意义的,因为如果浏览器不理解.async=…它不会理解“async”属性。

希望这是我正在进行的“非最小化GAPI”研究项目的有益见解。如果我说错了,请指正。