【第二届字节青训营】写好 JS 原则 - 各司其责

127 阅读4分钟

写好 JS 的一些原则

  • 各司其责
  • 组件封装
  • 过程抽象

各司其责

  • HTML / CSS / JS 各司其责
  • 应当避免不必要的由 JS 直接操作样式
  • 可以用 class 来表示状态
  • 纯展示类交互寻求零 JS 方案

现在看这个例子:

写一段 JS,控制一个网页,让它支持浅色和深色两种浏览模式

下面是 HTML 代码和 CSS 代码

<header>
  <button id="btn">🌞</button>
  <h2>四季</h2>
</header>

<main>
  <img src="https://p1.music.126.net/3lng9U9O2GzymvAR3sl87w==/109951166578471297.jpg?param=177y177" alt="" />
  <p>
    春、夏、秋、冬,你最喜欢哪一个季节? 你最喜欢的,可能是陈奕迅的〈四季〉。
    这一年忙于世界巡回的陈奕迅,仍不忘制作全新作品以慰歌迷。 2016年首支广东新歌〈四季〉由
    周国贤作曲,小克填词,此创作班底继〈张氏情歌〉后再度携手,打造充满人生哲理的作品!
    小克更透露,歌词灵感源自于林振强当年为张国荣所填写之〈春夏秋冬〉,同样是运用一年四季,传递
    出人生际遇中如季节变换般的生命体会。
    如果人生如四季,不知我们会有多少变化、多少际遇?但不论任何经历,都会在季度里事过境迁 ;没
    有过去,又那有今天看透世事的人生历练。
  </p>
</main>
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  transition: all 1s;
}

body {
  padding: 100px;
  box-sizing: border-box;
}

#btn {
  font-size: 2rem;
  float: right;
  border: none;
  background: transparent;
}

第一版

const btn = document.getElementById('btn');

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 中操作了 CSS。

而且这段代码的扩展性也不好,若想新加一种颜色,是需要修改原来代码的

第二版

因为第一版是一个一个更改 CSS 某个属性,造成了多次重绘(这样会导致性能上的损耗),所以可以采用更换类名的方式来改变 CSS 样式

在原来的基础上添加如下 CSS 样式:

.night {
  background-color: black;
  color: white;
}
const btn = document.getElementById('btn');

btn.addEventListener('click', (e) => {
  const body = document.body;
  if (body.className !== 'night') {
    body.className = 'night'
  } else {
    body.className = ''
  }
});

现在也可以实现改变深浅主题的效果。

第三版

问:在什么情况下 JS 代码不会出错。毫无疑问,在不写 JS 代码的情况下就不会出错。

所以这个版本就是不采用 JS 代码的基础上实现这个效果。

重新写 HTML 代码和 CSS 代码

<input id="modeCheckBox" type="checkbox" />

<div class="content">
  <header>
    <label id="btn" for="modeCheckBox"></label>
    <h2>四季</h2>
  </header>

  <main>
    <img src="https://p1.music.126.net/3lng9U9O2GzymvAR3sl87w==/109951166578471297.jpg?param=177y177" alt="" />
    <p>
      春、夏、秋、冬,你最喜欢哪一个季节? 你最喜欢的,可能是陈奕迅的〈四季〉。
      这一年忙于世界巡回的陈奕迅,仍不忘制作全新作品以慰歌迷。 2016年首支广东新歌〈四季〉由周国贤作曲,小克填词,此创作
      班底继〈张氏情歌〉后再度携手,打造充满人生哲理的作品!
      小克更透露,歌词灵感源自于林振强当年为张国荣所填写之〈春夏秋冬〉,同样是运用一年四季,传递出人生际遇中如季节变换般的生命体会。
      如果人生如四季,不知我们会有多少变化、多少际遇?但不论任何经历,都会在季度里事过境迁 ;没有过去,又那有今天看透世事的人生历练。
    </p>
  </main>
</div>
body,
html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
}

body {
  box-sizing: border-box;
}

.content {
  height: 100%;
  padding: 10px;
  transition: background-color 1s, color 1s;
}

#modeCheckBox {
  display: none;
}

#modeCheckBox:checked + .content {
  background-color: black;
  color: white;
  transition: all 1s;
}

#btn {
  font-size: 2rem;
  float: right;
}

#btn::after {
  content: "🌞";
}

#modeCheckBox:checked + .content #btn::after {
  content: "🌜";
}

这个实现原理其实就是利用一个复选框,复选框状态改变则主题改变;再利用 label 标签中的 for 属性与这个复选框关联起来,当点击 label 标签则复选框状态改变

再将复选框使用 display: none 将其隐藏,现在就只用 label 标签才能改变复选框状态

现在将复选框显示出来,查看其效果

可以看到点击图标后,复选框的状态也随之改变

这就是 JS 的其中一个原则:各司其责

最后

在青训营学习过程中,还是发现了自己有很多欠缺的。比如这个不用 JS 切换主题效果就挺开眼界的。

果然只要思想不滑坡,方法总比困难多。😂

若有不当之处,欢迎评论指出