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之WEB开发调试利器:Firebug 下载
Jan 13 Javascript
在IE,Firefox,Safari,Chrome,Opera浏览器上调试javascript
Dec 02 Javascript
高亮显示web页表格行的javascript代码
Nov 19 Javascript
用dtree实现树形菜单 dtree使用说明
Oct 17 Javascript
JSF中confirm弹出框的用法示例介绍
Jan 07 Javascript
学习使用jquery iScroll.js移动端滚动条插件
Mar 24 Javascript
简单实现js间歇或无缝滚动效果
Jun 29 Javascript
jQuery使用animate实现ul列表项相互飘动效果示例
Sep 16 Javascript
JavaScript直接调用函数与call调用的区别实例分析
May 22 Javascript
简单了解前端渐进式框架VUE
Jul 20 Javascript
详解JavaScript 中的批处理和缓存
Nov 19 Javascript
vue-video-player 断点续播的实现
Feb 01 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 数据库树的遍历方法
2009/02/06 PHP
ThinkPHP添加更新标签的方法
2014/12/05 PHP
PHP实现图片上传并压缩
2015/12/22 PHP
PHP中常用的魔术方法
2017/04/28 PHP
PHP var关键字相关原理及使用实例解析
2020/07/11 PHP
$()JS小技巧
2007/07/21 Javascript
jquery 应用代码 方便的排序功能
2010/02/06 Javascript
基于编写jQuery的无缝滚动插件
2014/08/02 Javascript
node.js中的events.emitter.listeners方法使用说明
2014/12/10 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
基于jquery实现瀑布流布局
2020/06/28 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
2016/09/04 Javascript
微信小程序中使用Promise进行异步流程处理的实例详解
2017/08/17 Javascript
extract-text-webpack-plugin用法详解
2019/02/14 Javascript
详解easyui 切换主题皮肤
2019/04/04 Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
2019/05/30 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
Python实现数据库编程方法详解
2015/06/09 Python
PyQt5每天必学之布局管理
2018/04/19 Python
Python访问MongoDB,并且转换成Dataframe的方法
2018/10/15 Python
Python中sorted()排序与字母大小写的问题
2020/01/14 Python
python使用Thread的setDaemon启动后台线程教程
2020/04/25 Python
多视角3D可旋转的HTML5 Logo动画
2016/03/02 HTML / CSS
日本著名的平价时尚女性购物网站:Fifth
2016/08/24 全球购物
NFL欧洲商店(德国):NFL Europe Shop DE
2018/11/03 全球购物
大学生关于奋斗的演讲稿
2014/01/09 职场文书
出纳会计岗位职责
2014/03/12 职场文书
信访工作经验交流材料
2014/05/23 职场文书
爱护花草树木的标语
2014/06/11 职场文书
空气的环保标语
2014/06/12 职场文书
领导班子“四风问题”“整改方案
2014/10/02 职场文书
师德自我剖析材料范文
2014/10/06 职场文书
用python批量解压带密码的压缩包
2021/05/31 Python
分析并发编程之LongAdder原理
2021/06/29 Java/Android
Spring Boot 使用 Spring-Retry 进行重试框架
2022/04/24 Java/Android