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 相关文章推荐
什么是JavaScript
Aug 13 Javascript
javascript 限制输入脚本大全
Nov 03 Javascript
javascript定时保存表单数据的代码
Mar 17 Javascript
JavaScript下通过的XMLHttpRequest发送请求的代码
Jun 28 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
May 23 Javascript
多个jQuery版本共存的处理方案
Mar 17 Javascript
微信JSAPI支付操作需要注意的细节
Jan 10 Javascript
JavaScript实现时间表动态效果
Jul 15 Javascript
VUE基于NUXT的SSR 服务端渲染
Nov 30 Javascript
vue+iview框架实现左侧动态菜单功能的示例代码
Jul 23 Javascript
jquery+ajax实现异步上传文件显示进度条
Aug 17 jQuery
VUE递归树形实现多级列表
Jul 15 Vue.js
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
PHP编码转换函数 自动转换字符集支持数组转换
2012/12/16 PHP
php解析url的三个示例
2014/01/20 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
ThinkPHP实现递归无级分类――代码少
2015/07/29 PHP
PHP pthreads v3下同步处理synchronized用法示例
2020/02/21 PHP
基于jquery的时间段实现代码
2012/08/02 Javascript
在浏览器窗口上添加遮罩层的方法
2012/11/12 Javascript
浅谈jQuery双事件多重加载的问题
2016/10/05 Javascript
动态加载css方法实现和深入解析
2017/01/18 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
2017/02/16 Javascript
vue实现在表格里,取每行的id的方法
2018/03/09 Javascript
element UI upload组件上传附件格式限制方法
2018/09/04 Javascript
js实现按钮开关单机下拉菜单效果
2018/11/22 Javascript
深入了解JavaScript 私有化
2019/05/30 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
2020/02/09 Javascript
Python的Bottle框架中获取制定cookie的教程
2015/04/24 Python
Python实现简单的代理服务器
2015/07/25 Python
详解程序意外中断自动重启shell脚本(以Python为例)
2019/07/26 Python
python利用re,bs4,requests模块获取股票数据
2019/07/29 Python
Python 经典算法100及解析(小结)
2019/09/13 Python
Python迷宫生成和迷宫破解算法实例
2019/12/24 Python
python爬虫实现POST request payload形式的请求
2020/04/30 Python
利用python汇总统计多张Excel
2020/09/22 Python
css3 线性渐变和径向渐变示例附图
2014/04/08 HTML / CSS
福克斯租车:Fox Rent A Car
2017/04/13 全球购物
BCBG官网:BCBGMAXAZRIA
2017/12/29 全球购物
希腊品牌鞋类销售网站:epapoutsia.gr
2020/03/18 全球购物
Smilodox官方运动服装店:从运动服到健身配件
2020/08/27 全球购物
自荐信需注意事项
2014/01/25 职场文书
2014社区三八妇女节活动总结
2014/03/01 职场文书
《回乡偶书》教学反思
2014/04/12 职场文书
四风问题班子对照检查材料
2014/09/27 职场文书
2014年减负工作总结
2014/12/10 职场文书
租赁协议书
2015/01/27 职场文书
酒店服务员岗位职责
2015/02/09 职场文书
《艾尔登法环》Boss腐烂树灵很有可能是《黑暗之魂3》的一个废案
2022/04/11 其他游戏