JavaScript 编码原则之各司其责
让HTML、CSS、JavaScript职能分离
ep:页面模式的切换
版本1:
实现了一个点击按钮切换页面背景颜色和按钮图标的功能
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 = '🌞';
}
});
版本2:
使用js修改class名称。html是负责结构的,css负责表现,js负责行为。
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
const body = document.body;
if(body.className !== 'night') {
body.className = 'night';
} else {
body.className = '';
}
});
优化点:
- 使用 CSS 类名切换样式:代码2中使用了
body.className属性来切换页面的样式,而不是直接设置背景颜色、文字颜色和按钮图标。这样可以更好地利用 CSS 来管理和控制样式,使代码更简洁和可维护。 - 减少了样式的硬编码:代码2中不再直接指定背景颜色、文字颜色和按钮图标的具体值,而是通过添加或移除 CSS 类名来间接控制样式。这样可以使样式更具灵活性和可配置性,可以通过 CSS 样式表来定义不同的主题样式。
- 减少了重复代码:代码2中只有两个分支,无论是切换到夜间模式还是切换回白天模式,都只需改变
body.className的值。相比之下,代码1中需要分别设置背景颜色、文字颜色和按钮图标,存在重复的代码逻辑。
版本3:
使用了纯CSS来实现,主要利用了伪类选择器checked
<input id="modeCheckBox" type="checkbox">
<label id="modeBtn" for="modeCheckBox"></label>
#modeCheckBox {
display: none;
}
#modeCheckBox:checked + .content {
background-color: black;
color: white;
transition: all 1s;
}
#modeBtn {
font-size: 2rem;
float: right;
}
#modeBtn::after {
content: '🌞';
}
#modeCheckBox:checked + .content #modeBtn::after {
content: '🌜';
}
优化点:
- 使用复选框和标签结构:代码3中使用了一个隐藏的复选框(
<input type="checkbox">)和一个标签(<label>)来实现切换按钮的功能。这种结构利用了复选框的选中状态来控制样式的切换,使代码更简洁和语义化。 - 使用 CSS 选择器和伪类:代码3中使用了 CSS 选择器和伪类来选择元素并应用样式。通过
:checked伪类和兄弟选择器+,可以根据复选框的选中状态来选择相邻的元素,并应用相应的样式。这样可以避免了 JavaScript 代码的使用,减少了代码量和复杂性。 - 使用过渡效果:代码3中通过
transition属性为.content元素添加了过渡效果,使背景颜色和文字颜色的切换更平滑。这样用户在切换模式时可以获得更好的视觉体验。 - 使用伪元素
::after:代码3中使用了::after伪元素来添加按钮的图标内容。通过改变伪元素的content属性,可以实现按钮图标的切换,而无需修改 DOM 结构或使用 JavaScript。
总结:
- HTML/CSS/JS 各司其责应当
- 避免不必要的由JS
- 直接操作样式可以用
class - 来表示状态纯展示类交互寻求零JS方案