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

本文介绍了如何使用JavaScript编写轮播图组件,并通过解耦JS实现插件化、解耦HTML实现模板化,最终形成一个组件框架。文章详细展示了从基础的API无交互版到控制流交互版的轮播图实现,再到组件的重构,包括插件化、模板化和抽象化,旨在提升组件的封装性、正确性、扩展性和复用性。通过这样的实践,有助于理解组件封装和组件库的设计原理。
摘要由CSDN通过智能技术生成

在这里插入图片描述

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

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

今天我们来学习写好JavaScript的另一个原则:组件封装

1. 起步

先来看看组件的概念

组件是指Web页面上抽出来一个个包含模版(HTML)、功能(JS)和样式(CSS)的单元。

好的组件具备封装性、正确性、扩展性、复用性。

下面我们来看一个案例——轮播图

2. 轮播图案例

大家在刚接触前端的时候,一定都写过轮播图,还记得如何用原生JavaScript写一个电商网站的轮播图吗?

GIF 2021-8-25 9-45-08.gif

版本一:API无交互版

结构:HTML

轮播图是⼀个典型的列表结构,我们可以使⽤⽆序列表<ul>元素来实现。

这里类的命名有点讲究,是一种CSS规则名书命名规范,其中 slider 表示组件名,-list表示元素,__item表示具体元素项,--selected表示的是状态(看完CSS的代码你就知道为什么这样命名更好了~)

<div id="my-slider" class="slider-list">
  <ul>
    <li class="slider-list__item--selected">
      <img src="https://p5.ssl.qhimg.com/t0119c74624763dd070.png"/>
    </li>
    <li class="slider-list__item">
      <img src="https://p4.ssl.qhimg.com/t01adbe3351db853eb3.jpg"/>
    </li>
    <li class="slider-list__item">
      <img src="https://p2.ssl.qhimg.com/t01645cd5ba0c3b60cb.jpg"/>
    </li>
    <li class="slider-list__item">
      <img src="https://p4.ssl.qhimg.com/t01331ac159b58f5478.jpg"/>
    </li>
  </ul>
</div>

此时的页面,将图片以列表的形式展现出来

image.png

表现:CSS

  • 使用 CSS 绝对定位将图片重叠在同一个位置
  • 轮播图切换的状态使用修饰符(modifier)这里是 --checked
  • 轮播图的切换动画使用 CSS transition

再回顾一下这种讲究的CSS规则名命名规范,其中 slider 表示组件名,-list表示元素,__item表示具体元素项,--selected表示的是状态

这样命名,当组件多了,CSS多起来的时候,很容易分辨清楚这段CSS是哪个组件哪个元素哪个状态的样式规则

#my-slider{
   
  position: relative;
  width: 790px;
}

.slider-list ul{
   
  list-style-type:none;
  position: relative;
  padding: 0;
  margin: 0;
}

.slider-list__item,
.slider-list__item--selected{
   
  /* 这里使用绝对定位,可以将多张图片重叠在一起,当然要记得给父盒子开相对定位 */
  position: absolute;
  transition: opacity 1s;
  opacity: 0;
  text-align: center;
}

.slider-list__item--selected{
   
  transition: opacity 1s;
  opacity: 1;
}

image.png

最后我们需要通过JavaScript来控制页面的行为

行为:JS —— API

API 设计应保证原子操作,职责单一,满足灵活性。

image.png

// 创建一个Slider类,封装一些API
class Slider{
   
  constructor(id){
   
    this.container = document.getElementById(id);
    this.items = this.container
    .querySelectorAll('.slider-list__item, .slider-list__item--selected');
  }
  
  // 获取选中的图片元素:通过选择器`.slider__item--selected`获得被选中的元素
  getSelectedItem(){
   
    const selected = this.container
      .querySelector('.slider-list__item--selected');
    return selected
  }
  
  // 获取选中图片的索引值:返回选中的元素在items数组中的位置。
  getSelectedItemIndex(){
   
    return Array.from(this.items).indexOf(this.getSelectedItem());
  }
  
  // 跳转到指定索引的图片
  slideTo(idx){
   
    const selected = this.getSelectedItem();
    if(selected){
    
      // 将之前选择的图片标记为普通状态
      selected.className = 'slider-list__item';
    }
    const item = this.items[idx];
    if(item){
   
      // 将当前选中的图片标记为选中状态
      item.className = 'slider-list__item--selected';
    }
  }
  
  // 跳转到下一索引的图片:将下一张图片标记为选中状态
  slideNext(){
   
    const currentIdx = this.getSelectedItemIndex();
    const nextIdx = (currentIdx + 1) % this.items.length;
    this.slideTo(nextIdx);
  }
  
  // 跳转到上一索引的图片:将上一张图片标记为选中状态
  slidePrevious(){
   
    const currentIdx = this.getSelectedItemIndex();
    const previousIdx = (this.items.length + currentIdx - 1) % this.items.length;
    this.slideTo(previousIdx);  
  }
}

我们就可以通过手动调用API来使用轮播图了

const slider = new Slider('my-slider');
slider.slideTo(1);
slider.slideTo(2);
slider.slideNext();
slider.slidePrevious();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HFYIgIVZ-1629954724858)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/315ee5fea47743119b22df6e0107d338~tplv-k3u1fbpfcp-watermark.image)]

或者我们可以直接定义一个定时器,让他自动播放

const slider = new Slider('my-slider');
setInterval(() => {
    
    slider.slideNext(); 
}, 1000);

GIF 2021-8-25 21-35-50.gif

版本二 控制流交互版

我们要让用户可以控制我们轮播图的状态,所以需要设计一套控制流

结构 HTML

这里加入了一些控制轮播图的元素,比如两边控制前后翻图的箭头,下面控制选图的小圆点

<div id="my-slider" class="slider-list">
  <ul>
    <li class="slider-list__item--selected">
      <img src="https://p5.ssl.qhimg.com/t0119c74624763dd070.png"/>
    </li>
    <li class="slider-list__item">
      <img src="https://p4.ssl.qhimg.com/t01adbe3351db853eb3.jpg"/>
    </li>
    <li class="slider-list__item">
      <img src="https://p2.ssl.qhimg.com/t01645cd5ba0c3b60cb.jpg"/>
    </li>
    <li class="slider-list__item">
      <img src="https://p4.ssl.qhimg.com/t01331ac159b58f5478.jpg"/>
    </li>
  </ul>
  <a class="slide-list__next"></a>
  <a class="slide-list__previous"></a>
  <div class="slide-list__control">
    <span class="slide-list__control-buttons--selected"></span>
    <span class="slide-list__control-buttons"></span>
    <span class="slide-list__control-buttons"></span>
    <span class="slide-list__control-buttons"></span>
  </div>
</div>

表现:CSS

接下来我们来看看CSS样式

通过下面这段代

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值