• FLIP动画做拖拽排序效果


    先来看效果
    在这里插入图片描述

    index.html文件

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <link rel="stylesheet" href="./index.css" />
      </head>
      <body>
        <div class="list">
          <div draggable="true" class="list-item">1</div>
          <div draggable="true" class="list-item">2</div>
          <div draggable="true" class="list-item">3</div>
          <div draggable="true" class="list-item">4</div>
          <div draggable="true" class="list-item">5</div>
        </div>
        <script src="./Flip.js"></script>
        <script src="./index.js"></script>
      </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    index.css文件

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .list {
      width: 500px;
    }
    
    .list-item {
      margin: 5px 0;
      padding: 0 20px;
      line-height: 40px;
      height: 40px;
      background: linear-gradient(to right, #267871, #136a8a);
      color: #fff;
      cursor: move;
      user-select: none;
      border-radius: 5px;
    }
    .list-item.moving {
      background: transparent;
      color: transparent;
      border: 1px dashed #ccc;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    index.js文件

    const list = document.querySelector('.list');
    let sourceNode; // 当前正在拖动的是哪个元素
    let flip;
    list.ondragstart = (e) => {
      setTimeout(() => {
        e.target.classList.add('moving');
      }, 0);
      sourceNode = e.target;
      e.dataTransfer.effectAllowed = 'move';
      flip = new Flip(list.children, 0.3);
    };
    list.ondragover = (e) => {
      e.preventDefault();
    };
    list.ondragenter = (e) => {
      e.preventDefault();
      if (e.target === list || e.target === sourceNode) {
        return;
      }
      const children = Array.from(list.children);
      const sourceIndex = children.indexOf(sourceNode);
      const targetIndex = children.indexOf(e.target);
      if (sourceIndex < targetIndex) {
        list.insertBefore(sourceNode, e.target.nextElementSibling);
      } else {
        list.insertBefore(sourceNode, e.target);
      }
      flip.play();
    };
    
    list.ondragend = (e) => {
      e.target.classList.remove('moving');
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    Flip.js文件

    const Flip = (function () {
      class FlipDom {
        constructor(dom, duration = 0.5) {
          this.dom = dom;
          this.transition =
            typeof duration === 'number' ? `${duration}s` : duration;
          this.firstPosition = {
            x: null,
            y: null,
          };
          this.isPlaying = false;
          this.transitionEndHandler = () => {
            this.isPlaying = false;
            this.recordFirst();
          };
        }
    
        getDomPosition() {
          const rect = this.dom.getBoundingClientRect();
          return {
            x: rect.left,
            y: rect.top,
          };
        }
    
        recordFirst(firstPosition) {
          if (!firstPosition) {
            firstPosition = this.getDomPosition();
          }
          this.firstPosition.x = firstPosition.x;
          this.firstPosition.y = firstPosition.y;
        }
    
        *play() {
          if (!this.isPlaying) {
            this.dom.style.transition = 'none';
            const lastPosition = this.getDomPosition();
            const dis = {
              x: lastPosition.x - this.firstPosition.x,
              y: lastPosition.y - this.firstPosition.y,
            };
            if (!dis.x && !dis.y) {
              return;
            }
            this.dom.style.transform = `translate(${-dis.x}px, ${-dis.y}px)`;
            yield 'moveToFirst';
            this.isPlaying = true;
          }
    
          this.dom.style.transition = this.transition;
          this.dom.style.transform = `none`;
          this.dom.removeEventListener('transitionend', this.transitionEndHandler);
          this.dom.addEventListener('transitionend', this.transitionEndHandler);
        }
      }
    
      class Flip {
        constructor(doms, duration = 0.5) {
          this.flipDoms = [...doms].map((it) => new FlipDom(it, duration));
          this.flipDoms = new Set(this.flipDoms);
          this.duration = duration;
          this.flipDoms.forEach((it) => it.recordFirst());
        }
    
        addDom(dom, firstPosition) {
          const flipDom = new FlipDom(dom, this.duration);
          this.flipDoms.add(flipDom);
          flipDom.recordFirst(firstPosition);
        }
    
        play() {
          let gs = [...this.flipDoms]
            .map((it) => {
              const generator = it.play();
              return {
                generator,
                iteratorResult: generator.next(),
              };
            })
            .filter((g) => !g.iteratorResult.done);
    
          while (gs.length > 0) {
            document.body.clientWidth;
            gs = gs
              .map((g) => {
                g.iteratorResult = g.generator.next();
                return g;
              })
              .filter((g) => !g.iteratorResult.done);
          }
        }
      }
    
      return Flip;
    })();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
  • 相关阅读:
    RabbitMQ: Publish/Subscribe结构
    ssm基于Android系统的学习记录与提醒应用APP-计算机毕业设计
    C++第四次实验
    ICASSP2023年SPGC多语言AD检测的论文总结
    大学生面试JAVA程序员应该具备的JAVA面试题库
    STM32使用寄存器开发底层驱动学习(USART+DMA)
    CSS的两种渐变
    在SpringBoot项目中集成TDengine,并通过SQL对数据进行增删改查
    CSS快速入门基础篇(一)
    2023华为杯数学建模研赛A题B题C题D题E题F题思路代码成品分享
  • 原文地址:https://blog.csdn.net/qq_38053677/article/details/133717983