【青训营】月影老师告诉我写好JavaScript的三大原则——各司其责

·  阅读 1421
【青训营】月影老师告诉我写好JavaScript的三大原则——各司其责

YK菌从大学开始到现在一共学习了挺多语言的(C/java/matlab/pathon/),最后终于确定了JavaScript是我的本命语言,刚开始学的时候觉得JavaScript上手真的很快,很简单,但是随着自己学习的深入,发现JavaScript真的特别有意思,原型、闭包等特性,太有意思了!我爱JavaScript~

参加了这次字节青训营的活动,见到了传说中的月影老师,关键还听他给我们上了两节如何写好JS的课! 太赚啦,今天我把上课学的东西分享出来,和大家一起学习学习!~

月影老师告诉我们写好JavaScript(包括其他语言)的三大原则 ① 各司其责 ② 组件封装 ③ 过程抽象

当然其实不止这三个原则,但这三个可以说是相对重要的原则,所以我直接说的三大原则,实际上应该叫几大原则

今天我们来看看 第一大原则——各司其责

1. 起步

image.png

上次在HTML基础中说到前端的“三驾马车”,其中一个就是JavaScript,主要是负责页面的行为

那我们就要让 JavaScript 专门负责页面的行为,下面我们来看个例子

2. 深色模式

现在很多网页都支持浅色模式和深色模式的切换,那用 JavaScript 应该怎么实现呢?

GIF 2021-8-24 19-24-39.gif

新手版

首先我们来看看页面的结构 HTML

  <header>
    <button id="modeBtn">🌞</button>
    <h1>YK菌的博客写的特别不错~</h1>
  </header>

  <main>
    <div class="pic">
      <img src="https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/154b55eb36c8ae10f701e2d3d6cfb138~300x300.image">
    </div>
    <div class="description">
      <p>
        这里就是YK菌的博客啦,我之前是在C站写博客的,后来参加了青训营的活动,转来了掘金,社区很好~很多活动~以后常来掘金啦~~
        <hr />
        之前的博客和现在的一样,都是一些笔记之类的,我是前端新人,先以记笔记为主吧~~把笔记记好,慢慢拓展~
        <hr />
        <strong>YK菌</strong>,冲啊~~~~
      </p>
    </div>
  </main>
复制代码

然后我们来看看我们页面的样式 CSS

    body,
    html {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
      overflow: hidden;
    }

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

    #modeBtn {
      font-size: 2rem;
      float: right;
      border: none;
      background: transparent;
    }
复制代码

最后我们来看看我们页面的行为JavaScript

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 = '🌞';
  }
});
复制代码

我们来看看上面这段JavaScript代码的逻辑

  1. 获取切换按钮元素
  2. 给按钮绑定鼠标点击事件
  3. 获取页面body元素
  4. 判断当前按钮元素是🌞还是🌜
  5. 是🌞就将页面的背景色改成黑色,字体颜色改成白色,并将按钮元素变成🌜
  6. 否则说明按钮就是🌜,我们就将页面背景色改为白色,字体改为黑色,并将按钮元素变成🌞

作为前端新人的我,觉得这段代码还不错的~ 逻辑很清晰,功能也可以

但是 这段代码违背了我们各司其责这个原则的!

这里的JavaScript代码,既修改了元素的样式,也修改了元素的结构!!!

我们这样想,如果这段代码在没有任何上下文(HTML/CSS)的情况下,拿给一个人去阅读,他能读出什么意思来呢?大家可以停住思考一下~

其实只给你阅读这段JavaScript代码,你知道的只有这段代码会修改一些样式,修改一些结构,但是你不会知道这段JavaScript的含义是完成网页深色与浅色模式的切换这样一个功能的!

还有一些问题,如果让你把深色模式中的字体颜色换成别的颜色,是不是还要修改JS代码来操作呢?这种方法方便给黑白模式加上一些过渡效果吗?

所以说新手版的代码,不够好!可以进行优化

新手优化版

怎么优化呢?既然说到了各司其责,而且我们改变的是样式,我看可以通过用css给元素添加一些类的样式,让JavaScript修改他们的类名就可以了~这样JavaScript就不用直接操作style了,这不就实现了 样式与行为分离了嘛!我们来试试

先来看看页面的结构

  <header>
    <button id="modeBtn"></button>
    <h1>YK菌的博客写的特别不错~</h1>
  </header>

  <main>
    <div class="pic">
      <img src="https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/154b55eb36c8ae10f701e2d3d6cfb138~300x300.image">
    </div>
    <div class="description">
      <p>
        这里就是YK菌的博客啦,我之前是在C站写博客的,后来参加了青训营的活动,转来了掘金,社区很好~很多活动~以后常来掘金啦~~
        <hr />
        之前的博客和现在的一样,都是一些笔记之类的,我是前端新人,先以记笔记为主吧~~把笔记记好,慢慢拓展~
        <hr />
        <strong>YK菌</strong>,冲啊~~~~
      </p>
    </div>
  </main>
复制代码

页面的结构,除了按钮那里的🌞删去了,其他都是没有变化的

那我们再来看看页面的样式CSS

    body,
    html {
      width: 100%;
      height: 100%;
      max-width: 600px;
      padding: 0;
      margin: 0;
      overflow: hidden;
    }

    body {
      padding: 10px;
      box-sizing: border-box;
      transition: all 1s;
    }

    #modeBtn {
      font-size: 2rem;
      float: right;
      border: none;
      outline: none;
      cursor: pointer;
      background: inherit;
    }

    body.night {
      background-color: black;
      color: white;
      transition: all 1s;
    }

    #modeBtn::after {
      content: '🌞';
    }

    body.night #modeBtn::after {
      content: '🌜';
    }
复制代码
  1. 通过给button加after伪元素,提供🌞与🌜的内容,这样就不用JS来修改页面的结构了
  2. 通过设定night类名,让页面背景变黑字体颜色变白,实现黑色模式,并且加入过渡效果
  3. 这样元素就可以通过设置不同的类名展示不同的样式了

最后JavaScript就非常好写了

const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
  const body = document.body;
  if (body.className !== 'night') {
    body.className = 'night';
  } else {
    body.className = '';
  }
});
复制代码

通过这个代码,我们可以看到JavaScript做的仅仅是修改元素的类名className,没有直接操作页面的样式,可读性也得到了很大的提升。(因为类名可以很好的反应这次业务的需求试night黑色模式)

GIF 2021-8-24 19-54-01.gif

同时在CSS中可以做更多的一些操作,比如这里就加入了过渡的效果transition: all 1s;,使得用户体验更好!拓展性更高,如果要更改需求,比如要改变字体的颜色之类的,只需要改动CSS中的代码即可~

这里其实做的已经不错了~但是还有没更好的解决方案呢?

大师版

真正的大师,就是无招胜有招,不使用任何技能,就能让你折服!

我们这里给出大师版的解决方案就是——不写JavaScript

最好的JS代码,就是不写JS!!!如何写出没有bug的JS,那就是不写JS!!!

页面结构HTML

  <input id="modeCheckBox" type="checkbox">
  <div class="content">
    <header>
      <label id="modeBtn" for="modeCheckBox"></label>
      <h1>YK菌的博客写的特别不错~</h1>
    </header>

    <main>
      <div class="pic">
        <img src="https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/154b55eb36c8ae10f701e2d3d6cfb138~300x300.image">
      </div>
      <div class="description">
        <p>
          这里就是YK菌的博客啦,我之前是在C站写博客的,后来参加了青训营的活动,转来了掘金,社区很好~很多活动~以后常来掘金啦~~
          <hr />
          之前的博客和现在的一样,都是一些笔记之类的,我是前端新人,先以记笔记为主吧~~把笔记记好,慢慢拓展~
          <hr />
          <strong>YK菌</strong>,冲啊~~~~
        </p>
      </div>
    </main>
  </div>
复制代码

这里的结构和之前的差别有点大,首先用一个大盒子将我们要显示的内容包裹起来,然后通过label元素代替之前的button元素,将它指向大盒子外面的checkbox元素

接下来我们看看页面样式CSS是怎么定义的

    body,
    html {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
      overflow: hidden;
    }

    body {
      box-sizing: border-box;
    }

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

    #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: '🌜';
    }
复制代码

我们来分析一下这里的代码

  1. 由于HTML的结构,点击label就相当于点击了checkbox【为什么要用checkbox呢,因为他可以通过点击,记住用户的状态,勾选和不勾选的两个状态,刚好对应我们的白色模式和深色模式两种状态】
  2. 将大盒子外面的checkbox隐藏起来 display: none;(有label指向checkbox了)
  3. 通过 checkbox 的伪类选择器checked,点击checkbox就会触发这个伪类

:checked 选择器匹配每个已被选中的 input 元素(只用于单选按钮和复选框)。

  1. 通过相邻兄弟选择器 + 选择到checkbox下面的大盒子

相邻兄弟选择器 (+) 介于两个选择器之间,当第二个元素紧跟在第一个元素之后,并且两个元素都是属于同一个父[元素]的子元素,则第二个元素将被选中。

developer.mozilla.org/zh-CN/docs/…

  1. 这样就可以实现在CSS控制元素点击后的样式切换了

GIF 2021-8-24 20-48-12.gif

这简直妙级了~

我们将checkbox显示出来,看看

GIF 2021-8-24 22-04-58.gif

注意

这里的纯大师版本可能兼容性不太好,因为用到了相邻兄弟元素选择器,不考虑兼容性还是不错的选择。 还有就是大师版本在HTML中加入了一些小技巧从而改变了一些页面的结构,这可能需要一些经验才能想得到~

image.png

3. 最佳实践

  • HTML、CSS、JavaScript 各司其责
  • 应当避免不必要的由JS 直接操作样式
  • 可以用 class 来表示状态,类名具有不错的业务语义
  • 纯展示类交互寻求零JavaScript方案

更多相关博文

【青训营】月影老师告诉我写好JavaScript的三大原则——各司其责

【青训营】月影老师告诉我写好JavaScript的三大原则——组件封装

【青训营】月影老师告诉我写好JavaScript的三大原则——过程抽象

【青训营】月影老师告诉我写好JavaScript的四大技巧——风格优先

【青训营】月影老师告诉我写好JavaScript的四大技巧——保证正确

分类:
阅读
标签: