如何避免在 JS 中重复 "document.getElementById" 调用?

How to avoid repeating "document.getElementById" calls in JS?

这是一个例子:

document.getElementById("field_a").style.color = "red";
document.getElementById("field_b").style.color = "red";
document.getElementById("field_c").style.color = "red";
document.getElementById("field_d").style.color = "red";
document.getElementById("field_a").style.backgroundColor = "white";
document.getElementById("field_b").style.backgroundColor = "white";
document.getElementById("field_c").style.backgroundColor = "white";
document.getElementById("field_d").style.backgroundColor = "white";

是否可以用更少的代码行来实现同样的功能? 谢谢。

假设您要为所有内容分配相同的颜色,为什么不遍历字段名称列表?

fields = ['field_a', 'field_b', ...]
fields.forEach(field => {
    const fieldEl = document.getElementById(field);
    fieldEl.style.color = "red";
    fieldEl.style.backgroundColor = "white";
});

Array.prototype.forEach()

一个选项是向所有这些元素添加一个 class 并使用 document.getElementsByClassNamedocument.querySelectorAll 检索所有这些元素并循环应用规则。

var elements = document.getElementsByClassName("foo");
// or = document.querySelectorAll(".foo");

for (var element of elements) {
  element.style.color = "red";
  element.style.backgroundColor = "white";
}

您可以通过 document.querySelectorAll 和 Array.from()

创建一个节点列表

const nodeList = document.querySelectorAll('.field');
let elements = Array.from(nodeList);

elements.map(x => x.style.color = 'red');
<p class="field">Lorem</p>
<p class="field">Lorem</p>
<p class="field">Lorem</p>

使用函数。详细了解 DRY 和 SRP

fields = ['a', 'b', ...]

fields.forEach(field => {
  changeColor(field, "red", "white");
})

function changeColor(id, color, bgColor)
{
  let field = document.getElementById(id);
  field.style.color = color;
  field.style.backgroundColor = bgColor;
}

var fields = document.querySelectorAll ("[data-js='field']"); 将 return 所有具有属性 data-js = "field"

的元素

然后你可以用 fields.forEach 遍历这些元素,并像下面的代码一样设置每个元素的颜色和背景颜色

属性 data-field-type 可用于 select 特定字段。例如:var field_a = document.querySelector("[data-field-type='a']");

(代码中只使用了3个字段)

var fields = document.querySelectorAll ("[data-js='field']");

fields.forEach (function (_field){
  _field.style.color = "red";
});
<div data-js="field" data-field-type="a">field a</div>
<div data-js="field" data-field-type="b">field b</div>
<div data-js="field" data-field-type="c">field c</div>

直接回答你的问题:

const $ = document.getElementById.bind(document);

现在这些是等价的,您每次调用节省了 22 个字符:

$('field_a') == document.getElementById("field_a");

为了使您共享的示例代码更加简洁,您可以这样做:

const nodes = document.querySelectorAll('[id^=field_]');
const elems = [...nodes];
elems.forEach(({ style }) => style.color = 'red' || (style.backgroundColor = 'white'));
<span id=field_a>a</span>
<span id=field_b>b</span>
<span id=field_c>c</span>
<span id=field_d>d</span>

选择器 [id^=field_] 选择 idfield_ 开头的所有元素。 不幸的是,我们返回的是 NodeList 而不是 Array,因此它没有 .forEach 方法(如果有人能解释为什么这样设计,我将不胜感激)。

幸运的是,使用扩展运算符可以轻松地将大多数可迭代对象(如 NodeList)转换为 Array 的实例:

[...nodeList]

然后我们可以使用.forEach循环遍历它们中的每一个。

在我的示例中,我使用 ({ style }) 获取每个元素的 .style 属性,因为它是我们想要改变的唯一对象。