[AC作业] 切版挑战记录: 添加选择样式 + 如何固定table header

前言:

此次作业纪录要完成课程 demo的广告系统:作业切版挑战
作业预计时间是两小时,需要完成以下两个项目:

广告被选择时的样式

固定 table header

完成作品画面如下:
http://img2.58codes.com/2024/20153933nVXYWA92BG.jpg

第一项花了一小时完成,觉得开心,想说第二项看起来很简单......结果我整个卡住 !
第二项花了约三小时才完成 http://img2.58codes.com/2024/emoticon17.gif

回正文

如何使栏位被选择时添加样式呢?

第一个想法最近常练习的: 添加一个 className给要被选择的样式
推想流程:
首先,我是先寻找哪一个节点需要被定义样式 --> 找到tbody tr
确认要被当作目标的 checkbox
要被绑定的是 每一个checkbox (for loop)
当元素被点选后的变化是 checkbox的父元素

定义一个className: selectedRow,并先试着在我要选取的该栏 tr 试加 selectedRow 的class 确定效果

.selectedRow {  background: var(--main-color);}

PS. 这边使用的 var(--main-color) 是因为此专案有把所有的数字(CSS color 色号) 变数化,方便管控
http://img2.58codes.com/2024/20153933AWkRCh2S9x.jpg

定义好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

以上是我这次的学习记录整理
虽然中间几个尝试方式没有成功,但我都有从那些文章複习或领悟到一些观念
所以一起放上来~
有任何错误再麻烦指正~
http://img2.58codes.com/2024/emoticon41.gif


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章