乐趣区

关于程序员:H5实现类似微信可拖拽左右吸边浮动按钮

H5 实现相似微信可拖拽左右吸边浮动按钮

背景

之前我的项目需要产品经理要求实现一个 能够实时拖拽的按钮,刚好咱们挪动端 H5 用的调试工具 vconsole 也有相似性能,于是钻研了一下 vconsole 外面具体实现的源码,参考其中代码本人也实现了一个, 点击查看 demo 成果

而后在做另外一个需要的时候产品经理无心中看到我手机微信的那个能够拖拽并且能够主动左右吸附的浮窗按钮,说这个成果不错,就依照微信的这个成果来,于是在原来的那个根底上有实现了一个 相似微信可拖拽左右吸边浮动按钮,点击查看 demo 成果

技术实现

其实实现这个性能所应用到的技术点并不难,次要是要解决边界状况和各种细节

实现实时拖拽性能技术点:

  • 挪动端:监听 touchstarttouchmovetouchend 事件
  • PC 端:监听 mousedownmousemovemouseup 事件
  • 以及一些 dom 操作的 api,获取节点的地位等

实现源码

废话不多说,间接上源码,这里只放 js 代码,要看 html/css/js,间接能够在 demo 页面,按 F12 查看残缺内容

const app = new Vue({
  el: "#app",
  data: {
    isMove: false, // 是否在挪动
    isLeft: false, // 吸附右边
    mineBtnPos: {
      x: 0, // right
      y: 0, // bottom 该值必须是初始定位款式值的倍数(比方应用 750px 设计稿的须要设置初始值为设计稿的一半),否则首次拖拽可能会错位
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0,
    },
  },
  created() {this.mineBtnPos = Object.assign(this.mineBtnPos, this.btnInitStyle);
  },
  mounted() {this._bindEvent();
  },
  methods: {clickMineBtn() {location.href = "https://liaolongdong.com/";},
    /**
     * bind DOM events
     * @private
     */
    _bindEvent() {
      let that = this;
      let dWidth =
        document.documentElement.clientWidth || document.body.clientWidth;

      let $mineBtn = document.querySelector(".c-draggable-likewxfloat");
      let mWidth = $mineBtn.getBoundingClientRect().width;
      let bottomPx =
        parseFloat(window.getComputedStyle($mineBtn, null).bottom) || 0;
      that.mineBtnPos.y = bottomPx;
      $mineBtn.addEventListener("touchstart", function (e) {that.mineBtnPos.startX = e.touches[0].pageX;
        that.mineBtnPos.startY = e.touches[0].pageY;
      });
      $mineBtn.addEventListener("touchend", function (e) {
        that.mineBtnPos.x = that.mineBtnPos.endX;
        that.mineBtnPos.y = that.mineBtnPos.endY;

        // 减少左右吸附成果
        // that.mineBtnPos.x 的值是从左边开始计算的
        that.isMove = false;
        if (that.mineBtnPos.x < dWidth / 2) {
          that.mineBtnPos.x = 0;
          that.isLeft = false;
        } else {
          that.isLeft = true;
          that.mineBtnPos.x = dWidth - mWidth;
        }
        $mineBtn.style.right = that.mineBtnPos.x + "px";

        that.mineBtnPos.startX = 0;
        that.mineBtnPos.startY = 0;
      });
      $mineBtn.addEventListener("touchmove", function (e) {
        that.isMove = true;

        if (e.touches.length > 0) {let offsetX = e.touches[0].pageX - that.mineBtnPos.startX,
            offsetY = e.touches[0].pageY - that.mineBtnPos.startY;
          let x = that.mineBtnPos.x - offsetX,
            y = that.mineBtnPos.y - offsetY;

          // check edge
          if (x + $mineBtn.offsetWidth > document.documentElement.offsetWidth) {x = document.documentElement.offsetWidth - $mineBtn.offsetWidth;}
          if (
            y + $mineBtn.offsetHeight >
            document.documentElement.offsetHeight
          ) {y = document.documentElement.offsetHeight - $mineBtn.offsetHeight;}
          if (x < 0) {x = 0;}
          if (y < 0) {y = 0;}
          $mineBtn.style.right = x + "px";
          $mineBtn.style.bottom = y + "px";
          that.mineBtnPos.endX = x;
          that.mineBtnPos.endY = y;
          e.preventDefault();}
      });
    },
  },
});

demo 成果地址

  • H5 实现相似微信可拖拽左右吸边浮动按钮
  • H5 实现相似于 vconsole 的实时拖拽性能

本文由 mdnice 多平台公布

退出移动版