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 相关文章推荐
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
javascript 闭包
Sep 15 Javascript
AngularJS转换响应内容
Jan 27 Javascript
JavaScript中eval函数的问题
Jan 31 Javascript
javaScript数组迭代方法详解
Apr 14 Javascript
jquery if条件语句的写法
May 19 Javascript
JavaScript中最常见的三个面试题解析
Mar 04 Javascript
JS监听滚动和id自动定位滚动
Dec 18 Javascript
一文快速详解前端框架 Vue 最强大的功能
May 21 Javascript
Node绑定全局TraceID的实现方法
Nov 14 Javascript
vue使用canvas实现移动端手写签名
Sep 22 Javascript
浅谈Web Storage API的使用
Jun 23 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
多重?l件?合查?(二)
2006/10/09 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
2013/01/29 PHP
php之Smarty模板使用方法示例详解
2014/07/08 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
2014/11/12 PHP
在php和MySql中计算时间差的方法详解
2015/03/27 PHP
thinkphp微信开发(消息加密解密)
2015/12/02 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
jQuery 1.5.1 发布,全面支持IE9 修复大量bug
2011/02/26 Javascript
一个简单的瀑布流效果(主体形式自写)
2013/05/27 Javascript
js向上无缝滚动,网站公告效果 具体代码
2013/11/18 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
js获取图片宽高的方法
2015/11/25 Javascript
vue中父子组件注意事项,传值及slot应用技巧
2018/05/09 Javascript
json字符串传到前台input的方法
2018/08/06 Javascript
jQuery解析json格式数据示例
2018/09/01 jQuery
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
2019/07/13 Javascript
[09:43]DOTA2每周TOP10 精彩击杀集锦vol.5
2014/06/25 DOTA
python转换字符串为摩尔斯电码的方法
2015/07/06 Python
教你用Python写安卓游戏外挂
2018/01/11 Python
将matplotlib绘图嵌入pyqt的方法示例
2020/01/08 Python
Python如何定义有可选参数的元类
2020/07/31 Python
python爬虫使用requests发送post请求示例详解
2020/08/05 Python
初探CSS3中的calc()功能
2015/07/14 HTML / CSS
HTML5学习笔记之html5与传统html区别
2016/01/06 HTML / CSS
娇韵诗Clarins意大利官方网站:法国天然护肤品牌
2020/03/11 全球购物
戴尔新加坡官网:Dell Singapore
2020/12/13 全球购物
数控专业大学生的自我鉴定
2013/11/13 职场文书
安全生产标语
2014/06/06 职场文书
公司行政专员岗位职责
2014/08/24 职场文书
社会发展项目建议书
2014/08/25 职场文书
领导欢迎词致辞
2015/01/23 职场文书
Python基于Opencv识别两张相似图片
2021/04/25 Python
你喜欢篮球吗?Python实现篮球游戏
2021/06/11 Python
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers
微信小程序APP的生命周期及页面的生命周期
2022/04/19 Javascript