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。
添加回答
舉報