老师请检查

来源:4-4 自由编程

慕粉1112348

2024-03-04 23:11:03

/* css reset */
* {
  padding: 0;
  margin: 0;
}
a {
  text-decoration: none;
  outline: none;
}
img {
  vertical-align: top;
}

/* layout */
.slider-layout {
  width: 80%;
  height: 420px;
  margin: 0 auto;
}

/* slider */
.slider,
.slider-content,
.slider-item,
.slider-img {
  width: 100%;
  height: 100%;
}
.slider {
  overflow: hidden;
}
.slider-item {
  float: left;
}
.slider-animation {
  transition-property: transform;
  transition-duration: 0ms;
}
//父类
import {DEFAULTS,ELEMENT_NODE,SLIDER_ANIMATION_CLASSNAME} from './constants';
class BaseSlider {
    constructor(el, options) {
      if (el.nodeType !== ELEMENT_NODE)
        throw new Error('实例化的时候,请传入 DOM 元素!');
 
      // 实际参数
      this.options = {
        ...DEFAULTS,
        ...options
      };
 
      const slider = el;
      const sliderContent = slider.querySelector('.slider-content');
      const sliderItems = sliderContent.querySelectorAll('.slider-item');
 
      // 添加到 this 上,为了在方法中使用
      this.slider = slider;
      this.sliderContent = sliderContent;
      this.sliderItems = sliderItems;
 
      this.minIndex = 0;
      this.maxIndex = sliderItems.length - 1;
      this.currIndex = this.getCorrectedIndex(this.options.initialIndex);
 
      // 每个 slider-item 的宽度(每次移动的距离)
      this.itemWidth = sliderItems[0].offsetWidth;
 
      this.init();
    }
 
    // 获取修正后的索引值
    // 随心所欲,不逾矩
    getCorrectedIndex(index) {
      if (index < this.minIndex) return this.maxIndex;
      if (index > this.maxIndex) return this.minIndex;
      return index;
    }
 
    // 初始化
    init() {
      // 为每个 slider-item 设置宽度
      this.setItemsWidth();
 
      // 为 slider-content 设置宽度
      this.setContentWidth();
 
      // 切换到初始索引 initialIndex
      this.move(this.getDistance());
 
      // 开启动画
      if (this.options.animation) {
        this.openAnimation();
      }
    }
 
    // 为每个 slider-item 设置宽度
    setItemsWidth() {
      for (const item of this.sliderItems) {
        item.style.width = `${this.itemWidth}px`;
      }
    }
 
    // 为 slider-content 设置宽度
    setContentWidth() {
      this.sliderContent.style.width = `${
        this.itemWidth * this.sliderItems.length
      }px`;
    }
 
    // 不带动画的移动
    move(distance) {
      this.sliderContent.style.transform = `translate3d(${distance}px, 0px, 0px)`;
    }
 
    // 带动画的移动
    moveWithAnimation(distance) {
      this.setAnimationSpeed(this.options.speed);
      this.move(distance);
    }
 
    // 设置切换动画速度
    setAnimationSpeed(speed) {
      this.sliderContent.style.transitionDuration = `${speed}ms`;
    }
 
    // 获取要移动的距离
    getDistance(index = this.currIndex) {
      return -this.itemWidth * index;
    }
 
    // 开启动画
    openAnimation() {
      this.sliderContent.classList.add(SLIDER_ANIMATION_CLASSNAME);
    }
 
    // 关闭动画
    closeAnimation() {
      this.setAnimationSpeed(0);
    }
 
    // 切换到 index 索引对应的幻灯片
    to(index) {
      index = this.getCorrectedIndex(index);
      if (this.currIndex === index) return;
 
      this.currIndex = index;
      const distance = this.getDistance();
 
      if (this.options.animation) {
        return this.moveWithAnimation(distance);
      } else {
        return this.move(distance);
      }
    }
 
    // 切换上一张
    prev() {
      this.to(this.currIndex - 1);
    }
 
    // 切换下一张
    next() {
      this.to(this.currIndex + 1);
    }
 
    // 获取当前索引
    getCurrIndex() {
      return this.currIndex;
    }
  }
  export default base;
// 默认参数
export const DEFAULTS = {
    // 初始索引
    initialIndex: 0,
    // 切换时是否有动画
    animation: true,
    // 切换速度,单位 ms
    speed: 300
  };
  // base
 export const ELEMENT_NODE = 1;
 export const SLIDER_ANIMATION_CLASSNAME = 'slider-animation';
 export const leftbtn=37;
 export const rightbtn=39;
//创建实例
import Slider from "./Slider";
new Slider(document.querySelector('.slider'));
//绑定的默认事件
import { leftbtn,rightbtn } from "./constants";
export const keyboard={
    bindEvent(slider) {
        document.addEventListener(
          'keyup',
          ev => {
            if (ev.keyCode === leftbtn) {
              slider.prev();
            } else if (ev.keyCode === rightbtn) {
              slider.next();
            }
          },
          false
        );
      }
}
//子类
import base from "./base";
import { keyboard } from "./keyboard";
import 
class Slider extends BaseSlider {
    constructor(el, options) {
      super(el, options);
      this._bindEvent();
    }
    _bindEvent(){
        keyboard.bindEvent(this);
    }
  }
  export default Slider;
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Module 的基本用法</title>
    <link rel="stylesheet" href="./css/slider.css" />
  </head>
  <body>
    <div class="slider-layout">
      <div class="slider">
        <div class="slider-content">
          <div class="slider-item">
            <a href="javascript:;"
              ><img src="./imgs/1.jpg" alt="1" class="slider-img"
            /></a>
          </div>
          <div class="slider-item">
            <a href="javascript:;"
              ><img src="./imgs/2.jpg" alt="1" class="slider-img"
            /></a>
          </div>
          <div class="slider-item">
            <a href="javascript:;"
              ><img src="./imgs/3.jpg" alt="1" class="slider-img"
            /></a>
          </div>
          <div class="slider-item">
            <a href="javascript:;"
              ><img src="./imgs/4.jpg" alt="1" class="slider-img"
            /></a>
          </div>
        </div>
      </div>
    </div>
   <script src="./js/base.js" type="Module"></script>
   <script src="./js/index.js" type="Module"></script>
  </body>
</html>


写回答

1回答

好帮手慕小李

2024-03-05

同学你好,代码可以实现需求,并格式也很清爽这很棒。祝学习愉快!

0

前端工程师

前端入门如同写字,如果你不知道从哪开始,那就选择前端(含Vue3.x,React17,TS)

20327 学习 · 17877 问题

查看课程

相似问题