vue实现可拖拽移动悬浮球

封装悬浮球组件,文件名s-icons.vue
<template><div ref="icons" class="icons-container" :style="{ left: left + 'px', top: top + 'px' }"><slot></slot></div>
</template>
<script>
export default {name: 'FloatIcons',props: {// 滚动idscroller: {type: String,default: ''},// 距离上有下左的安全距离padding: {type: String,default: '10 10 10 10'},// 初始位置距离底部的距离bottom: {type: Number,default: 0}},data () {return {timer: null,currentTop: 0,clientWidth: 0,clientHeight: 0,itemWidth: 0,itemHeight: 0,left: null,top: null}},computed: {// 滚动对象,默认空返回windowscrollContainer () {if (this.scroller === '') {return window} else {return document.getElementById(this.scroller)}},// 安全距离safeArea () {return this.padding.split(' ')}},created () {// 屏幕宽度this.clientWidth = document.documentElement.clientWidth// 屏幕高度this.clientHeight = document.documentElement.clientHeight},mounted () {this.$nextTick(() => {// 获取滚动元素this.scrollContainer.addEventListener('scroll', this.handleScrollStart)const div = this.$refs.icons// 获取宽度this.itemWidth = this.$refs.icons.offsetWidththis.itemHeight = this.$refs.icons.offsetHeight// 设置位置this.left = this.clientWidth - this.itemWidth - this.safeArea[1]this.top = this.clientHeight - this.itemWidth - this.bottomdiv.addEventListener('touchstart', () => {div.style.transition = 'none'})div.addEventListener('touchmove', e => {// 阻止默认动作e.preventDefault()if (e.targetTouches.length === 1) {const touch = event.targetTouches[0]this.left = touch.clientX - this.itemWidth / 2this.top = touch.clientY - this.itemHeight / 2}})div.addEventListener('touchend', () => {div.style.transition = 'all 0.3s'// 手指放开left位置if (this.left > this.clientWidth / 2) {this.left = this.clientWidth - this.itemWidth - this.safeArea[1]} else {this.left = this.safeArea[3]}// 手指放开top位置if (this.top < this.safeArea[0]) {this.top = this.safeArea[0]} else if (this.top > this.clientHeight - this.itemHeight - this.safeArea[2]) {// 不低于最低// this.top = this.clientHeight - this.itemHeight - this.safeArea[2]this.top = this.clientHeight - this.itemHeight}})})},beforeDestroy () {this.scrollContainer.removeEventListener('scroll', this.handleScrollStart)},methods: {// 滚动时候执行handleScrollStart () {this.timer && clearTimeout(this.timer)this.timer = setTimeout(() => {this.handleScrollEnd()}, 300)this.currentTop = document.documentElement.scrollTop || document.body.scrollTopif (this.left > this.clientWidth / 2) {this.left = this.clientWidth - this.itemWidth / 2} else {this.left = -this.itemWidth / 2}},handleScrollEnd () {const scrollTop = document.documentElement.scrollTop || document.body.scrollTopif (scrollTop === this.currentTop) {if (this.left > this.clientWidth / 2) {this.left = this.clientWidth - this.itemWidth - this.safeArea[1]} else {this.left = this.safeArea[3]}clearTimeout(this.timer)}}}
}
</script>
<style lang="less" scoped>
.icons-container {display: flex;flex-direction: column;justify-content: center;align-items: center;position: fixed;background: #ffffff;box-shadow: 0px 2px 4px 0px rgba(0, 97, 209, 0.1);border: 1px solid rgba(21, 95, 186, 0.1);// border-radius: 50%;z-index: 1000;transition: all 0.3s;
}
</style>
在封装了一层组件引入s-icons.vue 文件,文件名goToHome.vue
<template><float-icons class="icons-warp" :bottom="bottom" :scroller="scroller"><div class="float-icon-item" @click="goHomeClick"><div class="home-title">返回顶部</div></div></float-icons>
</template>
<script>
import FloatIcons from './s-icons'
export default {components: {'float-icons': FloatIcons},props: {// 滚动idscroller: {type: String,default: ''},// 初始位置距离底部的距离bottom: {type: Number,default: 60}},created () {},methods: {goHomeClick () {// 跳转其他页面// window.history.go(-(window.history.length - 2))// 回到顶部window.scrollTo({top: 0,left: 0,behavior: 'smooth' // 平滑滚动效果})}}
}
</script>
<style lang="less" scoped>
.icons-warp {border-radius: 50%;.float-icon-item {display: flex;flex-direction: column;align-items: center;justify-content: center;position: relative;width: 52px;height: 52px;.home-title {font-size: 14px;font-weight: 400;color: #1763bf;}}
}
</style>
最后一步,引入到页面中
<template><div class="main"><h1>顶部</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>11111</h1><h1>底部</h1><GoToHome :bottom="bottom" /></div>
</template><script>
import GoToHome from './goToHome.vue'
export default {data () {return {bottom: 105}},methods: {},components: {GoToHome}
}
</script><style lang="less" scoped>
</style>
相关文章:
vue实现可拖拽移动悬浮球
封装悬浮球组件,文件名s-icons.vue <template><div ref"icons" class"icons-container" :style"{ left: left px, top: top px }"><slot></slot></div> </template> <script> export …...
立体库堆垛机的精密构造与功能(收藏版)
导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 在现代物流仓储体系中,堆垛机以其高效、精准的操作能力,成为了自动化存储与检索系统的关键所在。 其复杂的构造和多样化的…...
算法提高之你能回答这些问题吗
算法提高之你能回答这些问题吗 核心思想:线段树 用sum,lmax,rmax,tmax分别存线段长度,最大前缀,最大后缀,最大子段和 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 500010;int n,m;int w[N];s…...
C++-指针
在C中,指针是至关重要的组成部分。它是C语言最强大的功能之一,也是最棘手的功能之一。 指针具有强大的能力,其本质是协助程序员完成内存的直接操纵。 指针:特定类型数据在内存中的存储地址,即内存地址。 指针变量的定…...
Three.js 研究:2、如何让动画线性运动
1、默认的动画含有加速度并非线性的 制作好的动画很明显是非线性的,这是一个运动环,为了让环运行线性进行如下设置。 2、设置动画成为线性动画...
z3-加法器实验
补码器加减法,运算方法简介 我们要知道什么是补码的加法,我们为什么要用补码的加法? 补码的加法其实就是将两个补码形式的二进制数字直接相加,处理的时候忽略超出固定位数的进位。补码的加法运算和无符号二进制数的加法操作一样&…...
解决git克隆项目出现fatal无法访问git clone https://github.com/lvgl/lvgl.git
Windows 11系统 报错 $ git clone https://github.com/lvgl/lvgl.git Cloning into lvgl... fatal: unable to access https://github.com/lvgl/lvgl.git/: Failed to connect to github.com port 443 after 21141 ms: Couldnt connect to server 解决方法 git运行这两段代码…...
Vue中引入组件需要哪三步
在Vue中引入组件通常需要以下三步: 导入组件:首先,你需要在父组件中导入你想要使用的子组件。这通常是通过ES6的import语法完成的。 注册组件:接下来,你需要在父组件中注册这个子组件。这可以通过components选项完成&…...
到底该用英文括号还是中文括号?
这篇博客写的还挺详细的,不错。...
一个普通双非女生的秋招之路
大家好,我是小布丁。 先简单地做个自我介绍: 我今年本科毕业于某双非院校(属于那种没什么人听说过的小学校),学的是计算机专业,英语四级水平(没办法,六级确实没过)。我本…...
一个模型用了几层神经网络怎么算?
有权重参数的层算作一层,没有权重参数的就是参数不更新,不能称之为一层 有权重:卷积层、全连接层 没有权重的层:激活函数层、池化层 即数卷积层和全连接层的个数,就是这个模型用了几层神经网络。...
python获取cookie的方式
通过js获取cookie,避免反复登录操作。 经验证在JD上没有用,cookie应该无痕或者加密了,只能用单浏览器不关的模式来实现,但是代码留着,其他网站可能有用。 def cookie_set():driver webdriver.Chrome(optionschrome_…...
Nginx-狂神说
Nginx概述 公司产品出现瓶颈? 我们公司项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个jar包启动应用就够了,然后内部tomcat返回内容给用户。 但是慢慢的,使用我们平台…...
Python筑基之旅-运算符
目录 一、运算符 1、了解定义 2、理解意义 2-1、基本数据处理 2-2、条件判断 2-3、逻辑操作 2-4、赋值和更新 2-5、位操作 2-6、提高代码可读性 2-7、解决实际问题 2-8、学习其他编程语言的基础 3、探索方法 3-1、理解概念 3-2、练习基本运算 3-3、掌握优先级 …...
【Text2SQL】Spider 数据集
论文:Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task ⭐⭐⭐⭐⭐ EMNLP 2018, arXiv:1809.08887 Dataset: spider GitHub: github.com/taoyds/spider 一、论文速读 本文提出了 Text2SQL 方向的…...
语雀——云知识库/笔记
对于日常进行学习/创作或是记录学习、工作内容与心得的群体来说,能够及时同步的云笔记应用有着广泛的应用场景。近期,我也探索了许多款不同的软件应用,今天来分享一款很有特点的应用——语雀。 语雀,为每一个人提供优秀的文档和知…...
Java学习:电影查询简单系统
1.创建一个movice的对象来存放电影 里面设置构造器(有参和无参) package com.movie;public class movice {//创建一个movice的对象存放电影private int id;private String name;private double price;private double score;private String diector;pri…...
在Mac电脑下怎么部署QAnything?
在Mac电脑下部署QAnything,可以选择使用纯Python环境进行部署,这种方式不依赖GPU,适合在Mac等笔记本电脑上运行。以下是基于QAnything的纯Python环境安装教程的步骤[18]: 安装要求 Python 3.10(建议使用Anaconda3来管…...
单条16g和双条8g哪个好
单条16g和双条8g各有优劣,具体选择要根据个人需求和电脑配置来决定。 以下是一些参考信息: •单条16g内存的价格比双条8g内存的价格低,而且16g的内存容量大,一条内存十分的方便。 •两条8g内存可以组成双通道,电脑运行速度要快一些。 •对于普通使用电脑的人群与热衷于…...
Microsoft VBA Excel 去重小工具
问题简述 在本工作表中,A1:B3单元格样式如下,通过名称管理器B列的单元格被命名为"LinkFile"、“SheetName”、“InputArea”,请实现以下功能:读取Excel文件中的数据,去除重复的数据,并记录每个数…...
机器学习结合基因无关通路映射:从临床数据挖掘新药靶点
1. 项目概述:当机器学习遇见代谢通路,如何从数据中“挖”出新药靶点?在生物医学研究的前沿,我们正面临一个核心矛盾:一方面,我们拥有海量的临床数据,比如血糖、血压、BMI等指标;另一…...
别再只用Service了!ROS1 Action通信保姆级教程:从导航进度条到任务取消,手把手教你实现带反馈的机器人任务
别再只用Service了!ROS1 Action通信保姆级教程:从导航进度条到任务取消,手把手教你实现带反馈的机器人任务当你的机器人正在执行一个长达10分钟的导航任务时,突然发现目标点设置错误,这时候如果只能干等着任务完成或者…...
贵阳婚礼西服定制攻略:面料、工艺、版型避坑指南
婚礼西装是男士婚礼造型的核心,区别于日常商务正装,婚礼西服更看重版型精致度、面料质感、上身挺拔感以及镜头适配度。在贵阳备婚的新人,大多会放弃成品西装,选择专属定制服务。但本地婚礼西服定制市场参差不齐,很多新…...
人类防伪指南:为什么你越写错字,HR越信你是真人?
前言各位码农、算法侠、CtrlC/V十级学者请注意:你有没有过这样的经历?辛辛苦苦肝了一晚上文档,逻辑严密、语法丝滑、连Markdown都对齐得像军训方阵,结果老板幽幽来一句:“这真是你自己写的?”那一刻&#x…...
如何快速批量下载高质量歌词:ZonyLrcToolsX跨平台终极解决方案
如何快速批量下载高质量歌词:ZonyLrcToolsX跨平台终极解决方案 【免费下载链接】ZonyLrcToolsX ZonyLrcToolsX 是一个能够方便地下载歌词的小软件。 项目地址: https://gitcode.com/gh_mirrors/zo/ZonyLrcToolsX 还在为本地音乐库缺少歌词而烦恼吗࿱…...
长期使用Token Plan套餐在项目开发中的成本观察
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期使用Token Plan套餐在项目开发中的成本观察 在AI驱动的项目开发中,成本控制与预算管理是团队负责人必须面对的现实…...
NanaZip:现代Windows文件压缩问题的终极解决方案
NanaZip:现代Windows文件压缩问题的终极解决方案 【免费下载链接】NanaZip The 7-Zip derivative intended for the modern Windows experience 项目地址: https://gitcode.com/gh_mirrors/na/NanaZip 还在为Windows文件压缩工具界面老旧、功能单一而烦恼吗&…...
Autodesk Fusion 360在Linux上的技术实现与性能优化深度解析
Autodesk Fusion 360在Linux上的技术实现与性能优化深度解析 【免费下载链接】Autodesk-Fusion-360-for-Linux This is a project, where I give you a way to use Autodesk Fusion 360 on Linux! 项目地址: https://gitcode.com/gh_mirrors/au/Autodesk-Fusion-360-for-Linu…...
CMSIS-DAP调试器原理与应用:以Elektor mbed interface为例
1. 项目概述:Elektor mbed interface [150554] 是什么?如果你玩过ARM Cortex-M系列的单片机,尤其是NXP LPC800系列,那你可能对“CMSIS-DAP”这个调试器标准不陌生。它是由ARM官方推出的一个开源调试接口标准,最大的好处…...
UE5 Cesium项目里,如何把默认的飞行Pawn换成建筑漫游Pawn?保姆级迁移教程
UE5 Cesium项目建筑漫游Pawn迁移实战:从飞行模式到精细化浏览的完整指南当你在UE5中结合Cesium插件构建数字孪生场景时,DynamicPawn提供的全球飞行体验令人印象深刻。但当视角聚焦到单体建筑或室内空间时,那种仿佛操控无人机般的操作方式就显…...
