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多平台公布