JavaScript三大原则下 | 青训营

64 阅读5分钟

JavaScript三大原则

组件封装

用原生JS实现轮播图
需求:

  • 点击左按钮,当前这一张消失,出现上一张。
  • 点击右按钮,当前这一张消失,出现下一张。
  • 点击焦点按钮,当前这一张消失,出现某一张。

如下图所示 QQ截图20230823231049.png 实现要求:

  1. 图片循环播放:轮番图需要能够循环显示出一组图片,让用户能够连续浏览不同的图片。
  2. 自动播放和暂停:当用户不进行任何操作时,轮番图应该自动播放图片,但当用户鼠标悬停在图片上时,轮番图应该暂停播放。
  3. 图片标记和切换按钮:轮番图需要显示当前展示的是第几张图片,并提供切换按钮供用户手动切换图片。
  4. 响应式设计:轮番图需要适应不同设备的屏幕尺寸,确保在不同的设备上都有良好的显示效果。
  5. 动画效果:轮番图可以用动画效果实现图片的切换,例如淡入淡出、滑动等效果,用于提升用户体验。

代码:

<!DOCTYPE html>
 <html lang="en">
  <head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * { margin: 0; padding: 0; }
 
 ul, ol, li { list-style: none;}

 img { width: 100%; height: 100%;display: block; }

 .banner { width: 100%; height:500px;position:relative;
    margin: 50px 0;}

 .banner > ul { width: 100%;height: 100%;position: relative;}

 .banner > ul > li {width: 100%; height: 100%; 
 position: absolute;left: 0;top: 0;opacity: 0;
   transition: opacity .5s linear;}

 .banner > ul > li.active { opacity: 1;}

 .banner > ol { width: 200px;height: 30px;
position: absolute;left: 30px;bottom: 30px;
   background-color: rgba(0, 0, 0, .5);display: flex;
   justify-content: space-around;align-items: center;
   border-radius: 15px;}

 .banner > ol > li { width: 20px;height: 20px;
   background-color: #fff;border-radius: 50%;
   cursor: pointer;}
 
 .banner > ol > li.active {background-color: orange;}

 .banner > div {width: 40px;height: 60px;
 position: absolute;top: 50%;transform: translateY(-50%);
   background-color: rgba(0, 0, 0, .5);display: flex;
   justify-content: center; align-items: center;
   font-size: 30px; color: #fff;cursor: pointer;}
  
  .banner > div.left {left: 0;}
   
  .banner > div.right {right: 0;}
    </style>
 </head>
 <body>
   <div class="banner">
   <!-- 图片区域 -->
   <ul class="imgBox">
   <li class="active">
   <img src="img/01.png" alt="图片1"></li>
  <li><img src="img/02.png" alt="图片2"></li>
  <li><img src="img/03.jpg" alt="图片3"></li>
  <li><img src="img/04.jpg" alt="图片4"></li>
  </ul>
  <!-- 焦点区域 -->
  <ol>
    <li data-i="0" data-name="point" class="active"></li>
    <li data-i="1" data-name="point"></li>
    <li data-i="2" data-name="point"></li>
    <li data-i="3" data-name="point"></li>
  </ol>
  <!-- 左右切换按钮 -->
  <div class="left">&#x3C;</div>
  <div class="right">></div>
</div>
<script>
// 获取到所有承载图片的 li 和所有承载焦点的 li
var imgs = document.querySelectorAll('ul > li')
var points = document.querySelectorAll('ol > li')
var banner = document.querySelector('.banner')</script>
// 准备一个变量, 表示当前是第几张, 默认是 0, 因为默认显示的是索引第 0 张
var index = 0
// 书写一个切换一张的函数
// 约定:
//   参数为 true, 我们切换下一张
//   参数为 false, 我们切换上一张
//   参数为 数字, 我们切换到指定索引的那一张
function changeOne(type) {
  // 1. 让当前这一张消失
  imgs[index].className = ''
  points[index].className = ''
  // 2. 根据 type 传递来的参数, 来切换 index 的值
  if (type === true) {
    index++
  } else if (type === false) {
    index--
  } else {
    index = type
  }
  // 判定一下 index 的边界值
  if (index >= imgs.length) {
    index = 0
  }
  if (index &#x3C; 0) {
    index = imgs.length - 1
  }
  // 3. 让改变后的这一张显示出来
  imgs[index].className = 'active'
  points[index].className = 'active'
}
// 给 轮播图区域 盒子绑定点击事件
banner.onclick = function (e) {
  // 判断点击的是左按钮
  if (e.target.className === 'left') {
    console.log('点击的是左按钮')
    // 切换上一张, 调用 changeOne 方法传递参数为 false
    changeOne(false)
  }
  // 判断点击的是右按钮
  if (e.target.className === 'right') {
    console.log('点击的是右按钮')
    // 切换下一张, 调用 changeOne 方法传递参数为 true
    changeOne(true)
  }
  // 判断点击的是焦点盒子
  if (e.target.dataset.name === 'point') {
    console.log('点击的是焦点盒子')
    // 拿到自己身上记录的索引
    var i = e.target.dataset.i - 0
    // 切换某一张, 调用 changeOne 方法传递参数为要切换的索引
    changeOne(i)
   }
 }
   // 自动切换功能
   setInterval(function () {
  // 切换到下一张
  changeOne(true)
 }, 5000)  
 </style>

总结

这是一个简单的图片轮播器,具有切换、自动播放和手动切换功能。

  1. 在上方<style>标签中,存放着对各个元素的样式定义。
  2. <div class="banner">内部,有一个图片区域(<ul class="imgBox">),其中包含了一系列图片(<li>)。还存在一个焦点区域(<ol>),其中的列表项(<li>)对应每张图片。当前显示的列表项和图片都具有active类名。另外,左右切换按钮(<div class="left"><div class="right">)用于手动切换图片。
  3. <script>标签中,首先通过document.querySelectorAll方法获取到图片和焦点的元素。其中imgs为图片元素的集合,points为焦点元素的集合,banner为轮播图区域的元素。变量index表示当前显示的是第几张图片,初始值为0。changeOne函数用于切换图片。可以传入true表示切换至下一张,false表示切换至上一张,或者传入指定的索引来切换图片。
  4. banner.onclick中绑定点击事件,通过判断点击的是左/右按钮还是焦点盒子来触发切换事件。setInterval函数用于自动切换图片,每隔5秒调用一次changeOne(true)来切换至下一张图片。

JavaScript部分首先获取到图片元素、焦点元素和banner容器的引用。然后定义了一个changeOne函数来完成切换图片的功能,根据传入的参数来切换图片,并且更新对应的焦点。最后,在banner容器上绑定点击事件,根据点击的目标元素来判断是左切换按钮、右切换按钮还是焦点盒子的点击,并调用changeOne函数来进行相应的切换。同时,还设定了定时器,每隔5秒自动切换到下一张图片。

过程抽象

为了满足不同事件处理中的“只执行一次”的需求,我们可以将该功能进行抽象。这个过程被称为过程抽象。通过将这个功能定义为一个单独的函数或方法,我们可以在不同的事件处理中重复使用。

  • 用来处理局部细节控制的一些方法。
  • 函数式编程思想的基础应用。

操作次数限制:

  • 一些异步交互;

  • 一次性的HTTP请求

    const list = document . querySelector( 'ul' );  
           const buttons = list. querySelectorAll( 'button' );buttons. forEach( (button) =>  
    { 
    button. addEventListener( 'click' , (evt) => {  
    consttarget = evt. target ;  
        target . parentNode. className = ' completed' ;setTimeout(( ) => {  
    list. removeChild( target . parentNode );},2000 );  
    });  
    });
    
  1.  querySelector('ul'):通过选择器获取页面中第一个ul元素(文档中的一个元素)。这是一次异步操作,因为需要等待DOM加载完成才能执行。
  2.   querySelectorAll('按钮'):通过选择器获取页面中所有的button元素(文档中的多个元素)。这也是一次异步操作,需要等待DOM加载完成。
  3.   按钮.forEach():对按钮数组进行遍历操作,为每个按钮元素添加事件监听器。这是一次同步操作,因为在代码执行期间完成。
  4.   按钮.addEventListener('click', () => {...}):为每个按钮元素添加点击事件监听器。这是一次同步操作,因为在代码执行期间完成。
  5.    事件监听器内的代码逻辑包括:
    a.获取点击事件的目标元素 const target = evt.target;
    b. 修改目标元素的父节点的类名为"已完成" target.parentNode.className = 'finished';
    c. 设置一个延迟定时器,在两秒后执行
    d. 在定时器回调函数中,移除目标元素的父节点 列表.removeChild(target.parentNode);

以上涉及到的操作次数限制主要取决于页面中ul元素和button元素的数量。异步操作需要等待DOM加载完成,而同步操作提供了即时的执行。注意,HTTP请求并没有在提供的代码中体现,可能存在于其他部分的代码中。