第五届字节跳动青训营 前端进阶学习笔记(二)JavaScript编码规范

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

1.前言

本次课程主要讲解了有关JavaScript编码原则和代码优化的相关问题。

重点内容

  • HTML、CSS、JS各司其责
  • 具备正确性、扩展性、复用性的组件封装
  • 函数式编程思想
  • 代码优化

2.写好JS的一些基本原则

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

各司其责

首先良好的前端代码应该是HTML、CSS和JS三部分代码各司其责的也就是各自控制各自所负责的部分。主要需要注意以下几点

  • 避免不必要的由JS直接操作CSS
  • 使用class来切换样式而不是修改style
  • 能单独使用CSS实现的样式尽量使用CSS追求纯展示性内容0JS

比如在下面的一个例子中

image.png

我们来实现一个深色模式切换的功能通常会按照下面这种形式实现

image.png

这样当我们点击切换按钮的时候页面就会切换到深色模式显示。

image.png

但是上述代码还存在很强的优化空间首先我们可以通过class来优化这一过程减少DOM的操作次数。
image.png image.png

此外我们还能使用纯CSS的方法来实现这一功能。借助label标签和:checked伪类的特性我们在不借助JS代码的情况下实现了切换界面深浅主题的功能。

image.png image.png

组件封装

组件设计的基本原则封装性、正确性、扩展性、复用性

下面我们来封装一个轮播图组件

  • HTML结构

image.png

  • CSS样式

image.pngalt="image.png" />

- JS代码

image.png
首先构建轮播图组件的基本结构、展现效果和行为。

image.png
下一步我们开始构建轮播图的控件轮播图控件我们通过自定义事件的方式来控制原点控制的状态切换以此来与轮播图组件解耦。

image.png

image.png
这里我们在Silder的构造函数里定义控件的方法。并且新增了start和stop方法用来实现具体的控件行为。

class Slider {
      constructor(id, delay=3000) {
        this.container = document.querySelector(`#${id}`);
        this.sliders = document.querySelectorAll('.slider__item, .slider__item--selected');
        this.delay = delay;

        const controlContainer = document.querySelector('.slider__control');
        if(controlContainer) {
          const controls = document.querySelectorAll('.slider__control-item, .slider__control-item--selected');
          controlContainer.addEventListener('mouseover', evt=> {
            const idx = Array.from(controls).indexOf(evt.target);
            if(idx >= 0) {
              this.toslider(idx);
              this.stop();
            }
          });

          controlContainer.addEventListener('mouseout', evt=> {
            this.start();
          })

          this.container.addEventListener('silde', evt => {
            const idx = evt.detail.index;
            const selected = document.querySelector('.slider__control-item--selected');
            if(selected) {
              selected.className = 'slider__control-item';
            } 
            controls[idx].className && (controls[idx].className = 'slider__control-item--selected');
          })
        }

        const pre = document.querySelector('.slider__control--previouse');
        if(pre) {
          pre.addEventListener('click', evt => {
            this.stop();
            this.preslider();
            this.start();
            evt.preventDefault();
          })
        }
        
        const next = document.querySelector('.slider__control--next');
        if(next) {
          next.addEventListener('click', evt => {
            this.stop();
            this.nexslider();
            this.start();
            evt.preventDefault();
          })
        }
        
      }
      getCurrent() {
        const current = document.querySelector('.slider__item--selected');
        return current;
      }
      getCurrentIndex() {
        return Array.from(this.sliders).indexOf(this.getCurrent());
      }
      toslider(idx) {
        const current = this.getCurrent();
        if(current) {
          current.className = 'slider__item';
        }
        this.sliders[idx] && (this.sliders[idx].className = 'slider__item--selected');

        const detail = {
          index: idx
        };
        const event = new CustomEvent('silde', {bubbles: true, detail});
        this.container.dispatchEvent(event);
      }
      preslider() {
        const idx = this.getCurrentIndex();
        this.toslider((this.sliders.length + idx - 1) % this.sliders.length);
      }
      nexslider() {
        const idx = this.getCurrentIndex();
        this.toslider((idx + 1) % this.sliders.length);
      }
      start() {
        this.stop();
        this.timer = setInterval(()=>this.nexslider(), this.delay);
      }
      stop() {
        clearInterval(this.timer);
      }
    }

至此一个基本的轮播图组件就封装完毕了。

image.png

在上面的实现过程中我们在Slider类的构造函数中定义了各个控件的所有行为因此各控件的行为和Silder组件是高度耦合的。对此我们需要将各个控件的行为单独封装为插件然后通过安装插件的方式将插件安装在组件上以此来实现解耦。同时若日后我们需要增加控件时只需要添加相应的控件插件就行了。

image.png

image.png

image.png

image.png

在此基础上我们还可以进一步对模板进行封装即将控件对应的HTML代码也封装进插件中。

image.png

这样封装好之后我们只需要一组HTML标签就能展示整个轮播图组件了。

image.png

过程抽象

过程抽象就是利用函数式编程的思想来处理局部细节控制的一些方法。

  • 高阶函数

    • 以函数作为参数
    • 以函数作为返回值
    • 常用于作为函数装饰器
  • 常用高阶函数

    • Once
    • Throttle
    • Consumber
    • Iterative
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: JavaScriptJava