元素的名称属性对 querySelectorAll 不可见,并且不会出现在其 HTML 中

Gir*_*rpa 3 html javascript dom selectors-api

我想选择所有名称为 的列表项'viewer'

这将返回一个空的NodeList

document.querySelectorAll('[name="viewer"]');
Run Code Online (Sandbox Code Playgroud)

但这会返回一个包含正确项目的数组:

[...document.querySelectorAll('li')].filter(({ name }) => name == 'viewer');
Run Code Online (Sandbox Code Playgroud)

列表项是这样创建的:

const listItem = document.createElement('li');
listItem.name = 'viewer';
listItem.id = 'viewer-1337';
Run Code Online (Sandbox Code Playgroud)

当我在控制台中检查它们时,我id在它们的 HTML 中看到它们,但在它们的name. 例如

<li id="viewer-1337">foo</li>
Run Code Online (Sandbox Code Playgroud)

似乎他们确实name设置了属性,但无法通过document.querySelectorAll其 HTML访问或可见。

为什么不?

const names = ['foo', 'bar'];
names.forEach(name => {
  const li = document.createElement('li');
  li.id = 'viewer-' + name;
  li.name = 'viewer';
  li.innerHTML = name;
  const ul = document.querySelector('ul');
  ul.appendChild(li);
});

const nodeList = document.querySelectorAll('[name="viewer"]');
console.log([...nodeList]);

const array = [...document.querySelectorAll('li')].filter(({ name }) => name == 'viewer');
console.log(array);
Run Code Online (Sandbox Code Playgroud)
<ul></ul>
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 6

发生这种情况是因为该name属性被保留

name 获取或设置 DOM 中元素的 name 属性。它仅适用于以下元素:<a>, <applet>, <button>, <form>, <frame>, <iframe>, <img>, <input>, <map>, <meta>, <object>, <param>, <select>, and <textarea>.

当您将name作为元件的特性为这些类型之一,该元素将不会收到值的属性值。它仍然会放在nameJavaScript 对象的属性上,但不会放在属性中。

const div = document.createElement('div');
console.log(div.attributes.length);
div.name = 'foo';
console.log(div.attributes.length);
console.log(div.hasOwnProperty('name'));
Run Code Online (Sandbox Code Playgroud)

因此查询字符串[name="viewer"]不会选择元素(因为它们没有name属性),但[...document.querySelectorAll('li')].filter(({ name }) => name == 'viewer')可以工作,因为filter回调成功地name从元素的 JavaScript 表示中检索属性。

您可以通过将其放入数据集来修复它:

const names = ['foo', 'bar'];
names.forEach(name => {
  const li = document.createElement('li');
  li.id = 'viewer-' + name;
  li.dataset.name = 'viewer';
  li.innerHTML = name;
  const ul = document.querySelector('ul');
  ul.appendChild(li);
});

const nodeList = document.querySelectorAll('[data-name="viewer"]');
console.log(nodeList.length);
Run Code Online (Sandbox Code Playgroud)
<ul></ul>
Run Code Online (Sandbox Code Playgroud)