此次作業紀錄要完成課程 demo的廣告系統:作業切版挑戰
作業預計時間是兩小時,需要完成以下兩個項目:
完成作品畫面如下:
第一項花了一小時完成,覺得開心,想說第二項看起來很簡單......結果我整個卡住 !
第二項花了約三小時才完成
回正文
第一個想法最近常練習的: 添加一個 className給要被選擇的樣式
推想流程:
首先,我是先尋找哪一個節點需要被定義樣式 --> 找到tbody tr
確認要被當作目標的 checkbox
要被綁定的是 每一個checkbox (for loop)
當元素被點選後的變化是 checkbox的父元素
定義一個className: selectedRow,並先試著在我要選取的該欄 tr 試加 selectedRow 的class 確定效果
.selectedRow {
background: var(--main-color);
}
PS. 這邊使用的 var(--main-color) 是因為此專案有把所有的數字(CSS color 色號) 變數化,方便管控
定義好className, 接著來選定checkbox 目標,透過提供 callback函數的方式對 "change"事件新增處理器
使用 for loop 迴圈才可以綁定每一欄的checkbox
每一次 checkbox被點選"change",則會觸發 selectedItem函數
// target the check box
const checkbox = document.querySelectorAll(".table_cell--checkbox");
//bind the event(use for loop)
for (let i = 1; i < checkbox.length; i++) {
checkbox[i].addEventListener("change", selectedItem);
}
function selectedItem(element) {
// console.log('element:', element.target.parentElement.parentElement)
const selectedOneRow = element.target.parentElement.parentElement;
selectedOneRow.classList.toggle("selectedRow");
}
為什麼用change? change事件是可以將checkbox表單元素在被改變時觸發,input 事件會在輸入框輸入內容的當下被觸發,但是change事件則是在目前焦點離開輸入框後才觸發。
(參考文章: 重新認識 JavaScript: Day 16 那些你知道與不知道的事件們)
嘗試過程:
(1) 失敗的position:fixed
一開始嘗試Position: fixed, 雖固定了該欄,但thead欄位float,長寬也跑掉
起始位置沒有在第一行資料的上面
因為Fixed會定位在原本的位置,並在空間中被抽出位置,故被定位的thead會被後面的內容忽視,自動往前跑。
並且fixed的欄設置位置(top/bottom/right/left)時會以視窗來做定位
--> 故要把tbody的第一行位置往下推,但是寬度依然失效,網路上搜尋只找到如何配合父層視窗做width:100%
所以我再搜尋固定table header, 大多看到jquery和純CSS的文章或討論串
我去研究找純css的,看到許多人推 position:sticky + top: 0
但我的那一行thead 怎麼樣都沒有留在最上方啊啊啊啊啊
(2) 不懂裝懂的position:sticky + top: 0
參照stackoverflow的討論串作了以下一版,但沒有很了解為什麼這樣寫的做法,一樣失敗,而且只有部分幾格欄位有被凍結首行,也不是在top: 0
main {
overflow: scroll;
}
table {
position: relative;
border-collapse: collapse;
}
thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
background: var(--header-color);
color: var(--header-text-color);
}
tbody td:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
}
(3) 呈上,我從CSS-tricks 找到了失敗原因: CSS-tricks 參考資料
**The issue boils down to the fact that stickiness requires position: relative to work and that doesn’t apply to <thead> and <tr> in the CSS 2.1 spec.**
啊! 原來thead和tr 不被支援 position:sticky
刪除了thead 關鍵字依然卡在漂浮
(4) 最後我找了這篇! 用position:sticky凍結欄位(th)
標題很清楚寫了解決重點:"用position:sticky凍結欄位(th) sticky會跟著上一層的overfloat跑!!因此要定義一個外框(class="table-sticky-wrapper")"
將外面包一層div,定義寬高並且將首欄的th (z-index: 2) 和tbody的td (z-index: 1) 設出區別
就可以把裡面表格凍結首欄了!
成功了! 只是跟一開始想的不太一樣現在變成外面有scroll 裡面表格也有scroll, 覺得不好看~~
所以我將外層包的div 縮小高度,讓外層的高度不會因過高而產生overflow 的問題
.table_sticky_wrapper {
width: 100%;
height: 70vh; //這個div的高度
overflow: auto;
}
.main_table {
position: relative;
border-collapse: collapse;
}
.main_table th {
position: sticky;
top: 0;
background: var(--header-color);
vertical-align: center;
border-bottom: 0;
z-index: 2;
}
tbody td {
left: 0;
z-index: 1;
}
成品示意圖: 因為我不太想要scroll bar出現,所以就試著把它隱藏掉,順便練習一下如何修改scroll-bar樣式
以上是我這次的學習記錄整理
雖然中間幾個嘗試方式沒有成功,但我都有從那些文章複習或領悟到一些觀念
所以一起放上來~
有任何錯誤再麻煩指正~