vue app端拖动的样式

152 阅读1分钟

1、效果

app端拖动样式.gif

2、代码(直接可以运行)

<!-- 拖拽滑动效果 -->
<template>
  <div class="main">
    <div
      ref="moveDiv"
      @touchstart="down"
      @touchmove="move"
      @touchend="end"
      :style="{ top: top + 'px', left: left + 'px' }"
      class="drag_area"
      :class="dynamicStyle"
    ></div>
  </div>
</template>
 
<script>
export default {
  name: "drag",
  data() {
    return {
      // 动态样式
      dynamicStyle: "",
      flags: false,
      position: { x: 0, y: 0, left: 0, top: 0 },
      top: 0,
      left: 0,
      width:
        window.innerWidth ||
        document.documentElement.clientWidth ||
        document.body.clientWidth,
      height:
        window.innerHeight ||
        document.documentElement.clientHeight ||
        document.body.clientHeight,
    };
  },
  methods: {
    // 拖动开始的方法
    down(event) {
      // 拖动开始的操作
      this.flags = true;
      const refs = this.$refs.moveDiv.getBoundingClientRect();
      let touch = event;
      if (event.touches) {
        touch = event.touches[0];
      }
      this.position.x = touch.clientX;
      this.position.y = touch.clientY;
      this.position.left = refs.left;
      this.position.top = refs.top;
​
      this.dynamicStyle = ""; // 初始化动态的样式
    },
​
    // 拖动中的方法
    move(event) {
      // 拖动中的操作
      if (this.flags) {
        let touch = event;
        if (event.touches) {
          touch = event.touches[0];
        }
        const xPum = this.position.left + touch.clientX - this.position.x;
        const yPum = this.position.top + touch.clientY - this.position.y;
        this.left = xPum;
        this.top = yPum;
​
        // 拖动限制
        this.banOut();
        // 阻止页面的滑动默认事件
        document.addEventListener(
          "touchmove",
          function () {
            event.preventDefault();
          },
          { passive: false }
        );
      }
    },
​
    // 拖动结束方法
    end() {
      // 拖动结束的操作
      this.flags = false;
​
      if (this.height - this.top <= 200) {
        // 当抬起到达一定位置时,关闭div
        // 关闭
        this.dynamicStyle = "closeStyle";
      } else {
        // 否则,回到开始的位置
        this.top = 0; // 一定要设置初始值,否则第二次拖动的时候从第一次抬起的位置开始
        this.dynamicStyle = "returnTopStyle";
      }
    },
​
    // 拖动限制的操作
    banOut() {
      // 避免左右两边 拖动出界的限制
      const refs = this.$refs.moveDiv.getBoundingClientRect();
      if (this.left < 0) {
        this.left = 0;
      } else if (this.left > this.width - refs.width) {
        this.left = this.width - refs.width;
      }
    },
  },
};
</script>
 
 
<style  lang="scss" scoped>
.main {
  background-color: brown;
  height: -webkit-fill-available;
  .drag_area {
    width: 100%;
    height: 90%;
    background-color: dodgerblue;
    position: absolute;
    top: 0;
    left: 0;
  }
  // 关闭拖动时的样式
  .closeStyle {
      // 当top属性变化时 过渡时间为1.5s 规定以慢速结束的过渡效果
    transition: top 1.5s ease-out;
    -webkit-transition: top 1.5s ease-out; /* Safari */
    position: absolute;
    top: 100% !important;
  }
  // 拖动不到指定位置,就返回到原来的位置
  .returnTopStyle {
    transition: top 1.5s ease-out;
    -webkit-transition: top 1.5s ease-out; /* Safari */
    position: absolute;
    top: 0px !important;
  }
}
</style>

3、解释

为实现拖动结束时,整体回到原来的位置还是关闭。需要判断当前结束位置离顶部位置的距离,若没有超过某距离,则回到原来的位置,否则整体往下移动