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

Element's name property is invisible to querySelectorAll and doesn't appear in its HTML

我想 select 所有名称为 'viewer' 的列表项。

这个returns一个空NodeList:

document.querySelectorAll('[name="viewer"]');

但是这个 returns 一个包含正确项目的数组:

[...document.querySelectorAll('li')].filter(({ name }) => name == 'viewer');

列表项是这样创建的:

const listItem = document.createElement('li');
listItem.name = 'viewer';
listItem.id = 'viewer-1337';

当我在控制台中检查它们时,我在它们的 HTML 中看到它们的 id 而不是它们的 name。例如

<li id="viewer-1337">foo</li>

他们似乎确实设置了 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);
<ul></ul>

这是因为 name 属性是 reserved:

name gets or sets the name property of an element in the DOM. It only applies to the following elements: <a>, <applet>, <button>, <form>, <frame>, <iframe>, <img>, <input>, <map>, <meta>, <object>, <param>, <select>, and <textarea>.

当您设置不是这些类型之一的元素的name属性时,该元素将不是 接收该值作为属性值。它仍然会被放入 JavaScript 对象的 name 属性 中,但不会被放入属性中。

const div = document.createElement('div');
console.log(div.attributes.length);
div.name = 'foo';
console.log(div.attributes.length);
console.log(div.hasOwnProperty('name'));

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

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

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

由于 li 元素没有 name 属性,您不能使用 CSS 选择器来查找。只需使用 data-name 属性即可。它按预期工作,见下文:

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

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

是的,刚刚注意到@certainperformance out-performed 我又过了 6 分钟......;-)