終於結束了 fast checkout P1
又有時間跟心力可以來做自己想做的事情了,
到了DAY10,發現以前努力做的筆記,越來越派上用場,
看到畫面就自己在腦裡把畫面切好,
似乎慢慢變成前端思考,
就像學英文一樣,無聊沒事就用英文來思考語法,語法就會變好一樣。
雖然還不是一個合格的課畫面工人,
不過從00-Javascript30,一路走來
刻一個簡單的畫面,從三小時(不太熟),變成不用查資料20分鐘做出來,
來css都可以邊做邊想考慮得越來越好,
每次看到自己的成長,
真的有說不出來的喜悅,
不過.. 真想找人一起分享我的喜悅。 哈哈哈哈哈哈XD
臉頰的左側好像有一個心靈開關,每當覺得自己又進入新的問題的時候,就會把開關拉下,
讓自己沈澱個幾天,安安靜靜的蛻變。
10 - Hold Shift and Check Checkboxes
首次上傳:2020/10/19
主題
介紹如何使用Shift + 左鍵來完成連續區間選取,
在這篇的探索中,我增加了連續區間取消選取及部分問題的改善。
步驟
Step1. 基本設定
用querySelectorAll('.inbox input[type="checkbox"]
來把HTML中的checkbox選起來,
並設置一個變數let lastChecked;
作為稍後勾選位置的紀錄使用。
Step2. 觸發設定
把所有選取的checkboxes使用forEach
來加入addEventListener('click', handelCheck)
。
Step3. handelCheck
在這個function裡面,建立了一個區域變數let inBetween = false
來當作選取區間的標記,
並在每次觸發時檢查是否”有按著shift點擊”if(e.shiftKey && this.checked)
,
若有的話則再跑一次forEach
來透過inBetween
對每個checkbox進行區間標記,
把屬於區間內的checkbox勾起來,並記錄此次點擊的位置。
程式備註
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]'); let lastChecked;
function handleCheck(e) { let inBetween = false; if (e.shiftKey && this.checked) { checkboxes.forEach(checkbox => { if (checkbox === this || checkbox === lastChecked) { inBetween = !inBetween; console.log('STarting to check them inbetween!'); } if (inBetween) { checkbox.checked = true; } }); } lastChecked = this; }
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));
|
探索
一開始做完原本作者講述的方法(也就是上面那段)的做法後,
發現有些小問題,例如直接對著同一個checkbox點選會導致全選,
也沒有辦法做區間取消選取的功能,所以重新寫了一個可以區間選取/取消的版本。
分析動作
想一下會使用連續選取時,我自己的動作會有這幾種:
- 單選:單純的點一下進行勾選/取消
- 範圍選取:按住shift後點到其他checkbox
- 範圍取消:在2按住shift的狀態下,點到已勾選的checkbox
所以我依據這些動作分別寫了對應的功能。
程式備註
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]'); let click; let selectClick; let cancelClick; const handleCheck = function (e) { if (e.shiftKey && this.checked) { selectClick = this; selectBox(); } else if (e.shiftKey && !this.checked) { cancelClick = this; cancleBox(); } else if (this.checked) { click = this; selectClick = undefined; cancelClick = undefined; } else { click = undefined; selectClick = undefined; cancelClick = undefined; } function selectBox() { let inBetween = false; checkboxes.forEach(checkbox => { if (checkbox === selectClick || checkbox === click) { inBetween = !inBetween; } if (inBetween && click !== undefined && click !== selectClick) { checkbox.checked = true; } }) } function cancleBox(el) { let inBetween = false; checkboxes.forEach(checkbox => { if (checkbox === selectClick || checkbox === cancelClick) { inBetween = !inBetween; } if (inBetween || checkbox === selectClick) { checkbox.checked = false; } }) } }
checkboxes.forEach(checkbox => { checkbox.addEventListener('click', handleCheck) });
window.addEventListener('keyup', (e) => { if (e.keyCode === 16 || e.shiftKey) { click = undefined; }; })
|
[DEMO]