3 回答
TA贡献1846条经验 获得超7个赞
这就像问我的简单数字时钟应该使用哪种高端显卡?性能差异可以忽略不计。使用生活而不是let已经比您的实际问题产生更大的性能影响,而是数组索引与多个 ifs。
它仍然无关紧要。
关于选项,我发现它们都很难阅读,尤其是在按钮数量变大的情况下。
这个怎么样?
document.querySelector(".buttons").addEventListener("click", function(event) {
const button = event.target.closest("button[data-msg]");
if (button) {
document.querySelector("#msg").innerText = button.dataset.msg;
}
})
<div class="buttons">
<button type="button" data-msg="You are now viewing Tab number one">Tab1</button>
<button type="button" data-msg="You are now viewing Tab number two">Tab2</button>
<button type="button" data-msg="You are now viewing Tab number three">Tab3</button>
<button type="button" data-msg="You are now viewing Tab number four">Tab4</button>
</div>
<p id="msg">Message here</p>
海事组织 漂亮和声明性。并且易于扩展。
除了这些按钮之外,该条件if(button)
还涉及您可能添加其他div.buttons
可以单击的内容的可能性。
在.closest("button[data-msg]")
某些情况下,您可能会在可能触发事件的按钮内添加更多标记。我们想要<button data-msg="...">
TA贡献1868条经验 获得超4个赞
对于 4 项,甚至 40 项,性能无关紧要:计算机速度非常快,而且列表非常短。更重要的是阅读和维护的难度。
表现
但值得研究一些潜在的性能原则,特别是在列表方面,因为小列表有变大的恼人趋势。
类似的数组查找button[i]
是常数时间或 O(1)。这意味着无论button
获取多大的查找都将始终花费相同的时间。
而连续的 if 语句或 aswitch
必须尝试每一个,直到找到匹配的一个。最好的情况i
总是 0 并且必须比较 1 次。最坏的情况i
总是 3,它必须比较 4 次。如果i
分布均匀,则平均需要 2 次。这称为线性时间或 O(n),查找时间随着大小的增加而button
增加。如果button
变大两倍,则时间变长两倍。
随着数组查找button
变大,性能将保持不变。随着 if 语句button
变大,性能会变差。
可读性
现在,刚开始,你会发现线性代码更容易阅读。您会更喜欢按照执行顺序在页面上呈现所有内容。但是随着代码变得越来越复杂,这很快就会变得不堪重负,并且会导致大量的剪切和粘贴代码违反DRY 原则:不要重复自己。
有经验的程序员发现最好将尽可能多的细节推到其他地方,这样人们就可以清楚地看到重要的部分。重要的部分是它为每个添加消息的按钮生成单击处理程序msg
。不重要的是该信息究竟是什么。
通过从循环中提取函数,您可以使代码更简单,并可能节省一些内存。
var addMsgListener = function(element, message) {
element.addEventListener("click",
function() {
document.getElementById("msg").innerHTML = message;
}
)
};
var buttonMessages = [
"You are now viewing Tab number one",
"You are now viewing Tab number two",
"You are now viewing Tab number three",
"You are now viewing Tab number four"
]
var button = document.getElementsByTagName("button")
for (var i = 0, len = button.length; i < len; ++i) {
addMsgListener(button[i], buttonMessages[i]);
}
请原谅我可能很糟糕的 Javascript。
现在很清楚该循环的作用,它为每个按钮添加了一个消息侦听器。如果我关心消息监听器是什么,我可以选择查看addMessageListener
. 或者我可以跳过它。这使得代码“可略读”;人们可以阅读代码以了解它的作用,并且只在必要时深入了解细节。这不是线性阅读,但这是你会习惯并喜欢的东西。
请注意,addMsgListener
不再指msg
代也不button
。这些是由使用它的循环选择的。它现在是通用的,可用于其他元素和消息。
更多的可重用性现在将展现出来;事件和 id 是否需要硬编码?这种在不改变代码的情况下改变代码的过程称为重构。
维护
每次要更改消息时,都必须更改代码。如果要添加消息,则必须添加代码并重新编号。如果要删除消息,则必须删除代码并重新编号。如果要对消息重新排序,则必须重新编号。这需要开发人员进行 UI 更改。而且这个过程很容易出错,如果您删除了一条消息而忘记更改索引怎么办?
通过将消息放入数组中,您只需更改msg
. 如果要添加消息,请在 中添加一行msg
。如果要删除消息,请从 中删除一行msg
。如果要对消息重新排序,请重新排序msg
。
msg
不必存在于代码中,它可以进入配置文件,使非编码人员更容易更改。
远距离行动
这导致了我们的最后一个问题:msg
需要与按钮的长度和顺序相同。每次更改 HTML 时,都msg
可能需要更改,反之亦然。但是按钮及其消息位于不同的位置。这被称为远距离操作:更改代码的一部分会受到代码完全不同部分中的某些内容的影响。
为避免这种情况,您可以给每个按钮一个class
orid
并以此为它们的消息编制索引。这至少意味着按钮和消息不依赖于它们的确切顺序。如果您不确定哪些按钮将出现在 HTML 中,但希望为所有可能的按钮提供消息,这将很有用。
var msg = {
car: "🏎",
truck: "🚚",
train: "🚆",
plane: "✈"
}
你可以走另一条路;在 Javascript 中生成按钮及其消息。它仍然将有关每个按钮的所有信息保存在一起。如果按钮是动态的并且可以更改,这将很有用。
您可以按照 Thomas 的建议进行操作,并将消息附加到按钮本身。然后所有关于按钮的数据都在一起。如果您添加、删除或重新排序按钮,消息仍然有效。这允许人们只在 HTML 上工作。
TA贡献1757条经验 获得超8个赞
在这种情况下,使用tabindex或data-index属性可能是一个好主意。示例代码段不涉及循环并使用data-index.
var msg = [
"You are now viewing Tab number one",
"You are now viewing Tab number two",
"You are now viewing Tab number three",
"You are now viewing Tab number four"
]
document.body.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
if (e.target.tagName == 'BUTTON') {
document.getElementById('msg').innerHTML = msg[e.target.dataset['index']];
}
});
<button data-index="0">Tab1</button>
<button data-index="1">Tab2</button>
<button data-index="2">Tab3</button>
<button data-index="3">Tab4</button>
<br>
<p id="msg">Message here</p>
编辑
tabindex如果您将拥有大量选项卡,请尽量避免使用。以下部分摘自MDN
避免使用大于 0 的 tabindex 值。这样做会使依赖辅助技术的人难以导航和操作页面内容。相反,应按逻辑顺序编写包含元素的文档。
此外tabindex,最大值为 32767。
添加回答
举报