前言:
此次作业纪录要完成课程 demo的广告系统:作业切版挑战
作业预计时间是两小时,需要完成以下两个项目:
广告被选择时的样式
固定 table header
完成作品画面如下:
第一项花了一小时完成,觉得开心,想说第二项看起来很简单......结果我整个卡住 !
第二项花了约三小时才完成
回正文
如何使栏位被选择时添加样式呢?
第一个想法最近常练习的: 添加一个 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 boxconst 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 那些你知道与不知道的事件们)
如何使用纯CSS将表格冻结首栏?
尝试过程:
(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样式
我的成品codepen
以上是我这次的学习记录整理
虽然中间几个尝试方式没有成功,但我都有从那些文章複习或领悟到一些观念
所以一起放上来~
有任何错误再麻烦指正~