Vue实现仿iPhone悬浮球的示例代码


Posted in Javascript onMarch 13, 2020

悬浮球插件简单的效果图:

很遗憾,没找到太好的视频转gif的软件,压缩出来的大小超过了限制,就不放图了

可以参考其他人的图,效果一致:

Vue实现仿iPhone悬浮球的示例代码

简单实用案例:

<!-- 给定一个初始位置position,插槽中填写想滑动的部分 -->
<xuanfuqiu :position="position">
	<d-add-button @click="addPigFarm" add-item="猪场"></d-add-button>
</xuanfuqiu>

原理示意图

请结合代码注释来理解

Vue实现仿iPhone悬浮球的示例代码

悬浮球插件代码如下:

<template>
  <div>
    <div class="xuanfu" id="moveDiv" :style="position"
      @mousedown="down" @touchstart="down"
      @mousemove="move" @touchmove="move"
      @mouseup="end" @touchend="end">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "",
  components: {},
  props: {
    // 通过position来设置初始定位
    position: {
      type: Object,
      default: function() {
        return {
          top: "32.25rem",
          left: "18.34375rem"
        }
      }
    },
    // 通过fixed来禁用自由移动
    fixed: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      flags: false,
      positionTemp: { x: 0, y: 0 },  // 记录手指点击的位置
      nx: '', ny: '', dx: '', dy: '', xPum: '', yPum: '',
    }
  },
  watch: {},
  computed: {},
  methods: {
    // 实现移动端拖拽
    down(){
      if (this.fixed) {
        return
      }

      this.flags = true;
      var touch;
      // 该if判断是用touch还是mouse来移动
      if (event.touches) {
        touch = event.touches[0];
      } else {
        touch = event;
      }
      this.positionTemp.x = touch.clientX;  // 手指点击后的位置
      this.positionTemp.y = touch.clientY;
      
      this.dx = moveDiv.offsetLeft;  // 移动的div元素的位置
      this.dy = moveDiv.offsetTop;
      
      // console.log("moveDiv.offsetLeft", moveDiv.offsetLeft)
      // console.log("touch.clientX", touch.clientX)
    },
    move(){
      if(this.flags) {
        var touch ;
        if(event.touches){
          touch = event.touches[0];
        }else {
          touch = event;
        }
        this.nx = touch.clientX - this.positionTemp.x;  // 手指移动的变化量
        this.ny = touch.clientY - this.positionTemp.y;
        
        this.xPum = this.dx + this.nx;  // 移动后,div元素的位置
        this.yPum = this.dy + this.ny;
        
        let windowWidth = document.documentElement.clientWidth
        let windowHeight = document.documentElement.clientHeight
        // console.log("window.clientWidth", windowWidth)
        // console.log(this.xPum)
        // console.log(" moveDiv.clientWidth", moveDiv.clientWidth)
        
        if (this.xPum > 0 && (this.xPum + moveDiv.clientWidth < windowWidth)) {
        	// movediv的左右边,未出界
          moveDiv.style.left = this.xPum + "px";
        } else if (this.xPum <= 0) {
          // 左边出界,则左边缘贴边
          moveDiv.style.left = 0 + "px";
        } else if (this.xPum + moveDiv.clientWidth >= windowWidth) {
          // 右边缘出界
          moveDiv.style.left = (windowWidth - moveDiv.clientWidth) + "px";
          // console.log("dx", windowWidth - moveDiv.clientWidth)
        }
        // 上下未出界
        if (this.yPum > 0 && (this.yPum + moveDiv.clientHeight < windowHeight)) {
          moveDiv.style.top = this.yPum +"px";
        } else if (this.yPum <= 0) {
          // 上边缘出界
          moveDiv.style.top = 0 + "px"
        } else if (this.yPum + moveDiv.clientHeight >= windowHeight) {
          // 下边缘
          // console.log("windowHeight:", windowHeight)
          // console.log("moveDiv.clientHeight:", moveDiv.clientHeight)
          // console.log(this.yPum + moveDiv.clientHeight)
          moveDiv.style.top = windowHeight - moveDiv.clientHeight + "px"
        }

        // 阻止页面的滑动默认事件,为了只让悬浮球滑动,其他部分不滑动;如果碰到滑动问题,1.2 请注意是否获取到 touchmove, 系统默认passive: true,无法使用preventDefault
        // document.addEventListener("touchmove", function(){
        //  event.preventDefault();
        // }, { passive: false });
        // document.addEventListener("mousemove", function(){
        //   event.preventDefault();
        // }, { passive: false });
        document.addEventListener("touchmove", this.preventDefault, { passive: false })
        document.addEventListener("mousemove", this.preventDefault, { passive: false })
      }
    },
    //鼠标释放时候的函数,鼠标释放,移除之前添加的侦听事件,将passive设置为true,不然背景会滑动不了
    end(){
      this.flags = false
      // 注意事项,在添加和删除监听事件时,其function必须是同名的函数,不能为匿名函数。
      document.removeEventListener('touchmove',this.preventDefault, false)
      document.removeEventListener('mousemove',this.preventDefault, false)
      // 下面两句是保证在移除监听事件后,除了悬浮球的部分还能够滑动,如果不添加,则无法滑动
      document.addEventListener("touchmove", function(e) {
        window.event.returnValue = true
      })
      document.addEventListener("mousemove", function(e) {
        window.event.returnValue = true
      })
    },
    preventDefault(e) {
      e.preventDefault()
    }
  },
  created() {},
  mounted() {}
}
</script>

<style lang="scss" scoped>
.xuanfu {
  /* 如果碰到滑动问题,1.3 请检查 z-index。z-index需比web大一级*/
  z-index: 999;
  position: fixed; // 这里的定位方式有待考量,fixed的话存在未知设置不合理,跑出屏幕不显示的问题
}
</style>

到此这篇关于Vue实现仿iPhone悬浮球的示例代码的文章就介绍到这了,更多相关Vue 悬浮球内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js 小数取整的函数
May 10 Javascript
js中如何把字符串转化为对象、数组示例代码
Jul 17 Javascript
js实现最短的XML格式化工具实例
Mar 12 Javascript
原生js和jQuery写的网页选项卡特效对比
Apr 27 Javascript
JSON对象 详解及实例代码
Oct 18 Javascript
H5实现仿flash效果的实现代码
Sep 29 Javascript
使用3D引擎threeJS实现星空粒子移动效果
Sep 13 Javascript
node+koa2+mysql+bootstrap搭建一个前端论坛
May 06 Javascript
详解Vue+axios+Node+express实现文件上传(用户头像上传)
Aug 10 Javascript
mock.js模拟数据实现前后端分离
Jul 24 Javascript
vue双向绑定数据限制长度的方法
Nov 04 Javascript
js判断浏览器的环境(pc端,移动端,还是微信浏览器)
Dec 24 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
Mar 13 #Javascript
vue动态渲染svg、添加点击事件的实现
Mar 13 #Javascript
创建nuxt.js项目流程图解
Mar 13 #Javascript
微信小程序中的上拉、下拉菜单功能
Mar 13 #Javascript
JavaScript实现公告栏上下滚动效果
Mar 13 #Javascript
使用vue实现HTML页面生成图片的方法
Mar 12 #Javascript
JavaScript实现随机点名器
Mar 25 #Javascript
You might like
支持oicq头像的留言簿(一)
2006/10/09 PHP
《PHP编程最快明白》第四讲:日期、表单接收、session、cookie
2010/11/01 PHP
php 安全过滤函数代码
2011/05/07 PHP
在PHP中使用X-SendFile头让文件下载更快
2014/06/01 PHP
PHP数组相关函数汇总
2015/03/24 PHP
让你的PHP7更快之Hugepage用法分析
2016/05/31 PHP
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
JavaScript类和继承 prototype属性
2010/09/03 Javascript
JavaScript利用正则表达式去除日期中的“-”
2014/07/01 Javascript
jQuery 中$(this).index与$.each的使用指南
2014/11/20 Javascript
node.js中的fs.fchmod方法使用说明
2014/12/16 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
2015/04/17 Javascript
JavaScript制作简单的日历效果
2016/03/10 Javascript
jquery Ajax 全局调用封装实例详解
2017/01/16 Javascript
详解如何去除vue项目中的#——History模式
2017/10/13 Javascript
spirngmvc js传递复杂json参数到controller的实例
2018/03/29 Javascript
vue watch关于对象内的属性监听
2019/04/22 Javascript
解决vue-router路由拦截造成死循环问题
2020/08/05 Javascript
[51:15]完美世界DOTA2联赛PWL S2 PXG vs Magma 第一场 11.21
2020/11/24 DOTA
Python3 适合初学者学习的银行账户登录系统实例
2017/08/08 Python
Python使用Turtle模块绘制五星红旗代码示例
2017/12/11 Python
Django项目中用JS实现加载子页面并传值的方法
2018/05/28 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
2018/06/01 Python
python实现本地图片转存并重命名的示例代码
2018/10/27 Python
下载与当前Chrome对应的chromedriver.exe(用于python+selenium)
2020/01/14 Python
布局和排版教程 纯css3实现图片三角形排列
2014/10/17 HTML / CSS
使用CSS3制作响应式导航菜单的方法
2015/07/12 HTML / CSS
css3 实现元素弧线运动的示例代码
2020/04/24 HTML / CSS
水果超市创业计划书
2014/01/27 职场文书
工商干部先进事迹
2014/05/14 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
2014年导购员工作总结
2014/11/18 职场文书
2014年保洁工作总结
2014/11/24 职场文书
入党积极分子考察意见
2015/06/02 职场文书
法定代表人免职证明
2015/06/24 职场文书
《雷雨》教学反思
2016/02/20 职场文书