前端体系知识划分:
- 基础知识
- 通用基础知识(数学、逻辑、算法、数据结构和设计模式以及语言基础知识等)
- 专用基础知识(指HTML、CSS和JavaScript的基础)
- 领域知识
- 运行环境、工程化、框架和工具库以及细分领域
对于变化最快的领域知识,要以实用为出发点学习,掌握核心内容;专用和通用基础知识,需要深入学习,打好基础。
各司其职
- HTML:网页的结构
- CSS:网页元素的展示样式
- JS:网页和用户的交互
处理前端需求时,一定要遵循HTML、CSS、JS各司其职的原则,各自实现对应的功能,这样的好处不仅便于后续代码的维护扩展,而且可以做到代码简洁、可读性高。
HTML/CSS/JS职责实现举例
模式切换效果
比如一个深夜/白天模式切换的需求。点击"太阳🌞"图标,切换为深夜模式(深色背景、浅色字体、图标变为"月亮🌜")。
可以根据"图标"所在按钮,通过点击简单实现:
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
const body = document.body;
if(e.target.innerHTML === '') {
body.style.backgroundColor = 'black';
body.style.color = 'white';
e.target.innerHTML = '';
} else {
body.style.backgroundColor = 'white';
body.style.color = 'black';
e.target.innerHTML = '';
}
});
复制代码
这样效果就实现了。
但是,是否考虑了下面三点:
- 对于不了解需求的人,阅读这段代码是否可以直接理解"按钮"点击的含义?
- 如果需求变更,夜间模式改为深灰色背景、浅黄色文字,是否可以避免修改JS代码?
- 是否可以方便的添加切换过程的动画效果?
用class属性表示元素的业务状态
下面模式切换的js代码,直接阅读只知道是将background
改为黑色、color
改为白色。却不清楚该样式代表的业务需求或状态!
body.style.backgroundColor = 'black';
body.style.color = 'white';
复制代码
这是因为,本该由CSS完成的工作交由JS来做了,应该由CSS设置元素的样式。
如下,重构代码体现出业务的需求:
- CSS完成夜间模式样式
body.night {
background-color: black;
color: white;
}
复制代码
- JS代码重构为
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
const body = document.body;
if(body.className !== 'night') {
body.className = 'night';
e.target.innerHTML = '';
} else {
body.className = '';
e.target.innerHTML = '';
}
});
复制代码
这样修改的好处:
- className通过语义化的night,描述了这是一个夜间(night)模式的业务状态,便于快速了解业务需求和后续维护。
- 如果需求变更,修改模式的颜色。只需修改
body.night
的样式,不需要修改JS代码。 - 如果增加切换的动画效果,可以使用CSS3实现,如:
body {
padding: 10px;
box-sizing: border-box;
transition: all 1s;
}
body.night {
background-color: black;
color: white;
transition: all 1s;
}
复制代码
e.target.innerHTML = '🌜';
的切换也可以改进为,合并到CSS中(伪元素实现):
#modeBtn::after {
content: '';
}
body.night #modeBtn::after {
content: '';
}
复制代码
这样按钮#modeBtn
的文本内容就可以清除,js代码也更简洁。
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
const body = document.body;
if(body.className !== 'night') {
body.className = 'night';
} else {
body.className = '';
}
});
复制代码
JS代码只负责切换元素的状态,CSS改变元素的样式。
最好的JS代码是没有JS代码(纯CSS实现状态切换)
如何只使用CSS实现“夜间模式”效果?核心是:使用CSS代替JS来切换并记住与用户交互的状态。
在HTML中,能够完成状态切换的元素:复选框checkbox
、单选框Radio
、单选或多选选择列表select
。
通过input checkbox
元素的普通状态和选中状态,实现业务状态的切换:
<input id="modeCheckBox" type="checkbox">
复制代码
如下,选中时的样式
/* 匹配checkbox选中状态下的.content */
#modeCheckBox:checked + .content {
background-color: black;
color: white;
transition: all 1s;
}
复制代码
此时,通过点击checkbox
复选框实现模式的切换。
但是,还有个问题,无法通过点击🌞/🌜
按钮实现状态切换,而且页面多出个复选框(点击复选框也是一个麻烦)。
可以借助for属性
指定checkbox的id,比如label标签加for属性,实现点击label即点击表单元素,切换checkbox的状态,然后隐藏多出的checkbox。
<label id="modeBtn" for="modeCheckBox"></label>
复制代码
隐藏checkbox:
#modeCheckBox {
display: none;
}
复制代码
从而实现只用CSS,不使用JS代码切换模式状态。
完整代码如下,同时修改了js部分的代码处理,可以适用当前的布局:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>深夜食堂</title>
<style>
body,
html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
body {
box-sizing: border-box;
}
.content {
text-align: center;
padding: 10px;
transition: all 1s;
}
div.pic img {
width: 60%;
}
#modeCheckBox {
display: none;
}
#modeCheckBox:checked+.content,.content.night {
background-color: black;
color: white;
transition: all 1s;
}
#modeBtn {
font-size: 2rem;
float: right;
}
#modeBtn::after {
content: '';
}
#modeCheckBox:checked+.content #modeBtn::after,.content.night #modeBtn::after{
content: '';
}
</style>
</head>
<body>
<input id="modeCheckBox" type="checkbox">
<div class="content">
<header>
<label id="modeBtn" for="modeCheckBox"></label>
<h1>深夜食堂</h1>
</header>
<main>
<div class="pic">
<img src="https://p2.ssl.qhimg.com/t0120cc20854dc91c1e.jpg">
</div>
<div class="description">
<p>
内容。。。
</p>
</div>
</main>
</div>
</body>
<script>
// const btn = document.getElementById('modeBtn');
// btn.addEventListener('click', (e) => {
// const content = document.getElementsByClassName('content')[0];
// if (content.classList.contains('night')) {
// content.classList.remove('night');
// } else {
// content.classList.add('night');
// }
// });
</script>
</html>
复制代码
对比js版本和css版本
JS版本更加简洁,HTML结构更清晰简单。兼容性好一些。
CSS版本不用维护JS代码,尤其适用移动端。
唯一不会有bug的方式就是不写代码。所以,最好的JS代码就是没有JS代码
作者:代码迷途
链接:https://juejin.cn/post/6953611538485903367
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。