
這次的範例給我們的是一個list選單,而我們要實作的功能是當我們勾選了其中一個A選項,當我們壓著shift並且勾選B選項時,可以將A~B之間的選項一併勾選起來
作品實做
const checkBoxes = document.querySelectorAll('.inbox input[type="checkbox"]');
checkBoxes.forEach((checkBox) => {
checkBox.addEventListener("click", handleClick);
});
checkBoxes 選取inbox內含有type="checkbox”的input元素checkBox.addEventListener("click", handleClick) 監聽當click此元素時執行handleClick()
let lastKey = null;
function handleClick(e) {
if (e.shiftKey && lastKey !== null) {
let nowCheck = checkBoxes.indexOf(this);
checkBoxes
.slice(Math.min(nowCheck, lastKey), Math.max(nowCheck, lastKey))
.forEach((input) => {
input.checked = true;
});
}
if (this.checked) {
//假這有打勾 記下input的index
lastKey = checkBoxes.indexOf(this);
} else {
lastKey = null;
}
}
if (this.checked) 當我們勾選click並且此input元素是checked的狀態,lastKey賦值checkBoxes.indexOf(this) 如果false則lastKey = null
注意!
這時候我想要確認一下我點擊有沒有成功選取於是console.log(lastKey),但卻出現了此錯誤:

原來是因為 querySelectorAll 返回的是 NodeList,他是like Array卻不是Array,所以無法調用indexOf 這樣的陣列方法,所以在我們選取input的時候加上Array.from(),把nodeList轉換為陣列
const checkBoxes = Array.from(
document.querySelectorAll('.inbox input[type="checkbox"]')
);

這樣處理過後錯誤就消除了,顯示了我勾選的input的index!
if (e.shiftKey && lastKey !== null) 當按下shift時並且我們lastKey不是空值時執行以下的動作:
nowCheck 賦值為checkBoxes.indexOf(this) ,所以我們現在會有兩個值nowCheck 以及一開始勾選的lastKey
checkBoxes.slice(Math.min(nowCheck, lastKey), Math.max(nowCheck, lastKey)) 用來選出lastKey 以及nowCheck 之間的範圍,選取完使用input.checked = true ,這樣我們就可以連續選取了/