uniapp开发小程序实现全局悬浮按钮的代码

目录
  • 看效果
  • 须知:
    • 1.uni.getSystemInfoSync()获取手机的信息接口
    • 2.uni.createSelectorQuery().in(this)
    • 3.touchmove滑动事件
    • 取出存储的值
    • 赋值
    • 全局注册组件

看效果

这是一个全局的按钮,可以换成图片,自己写样式,每个页面都有;

须知:

1.uni.getSystemInfoSync()获取手机的信息接口

可以拿到手机屏幕的宽高

2.uni.createSelectorQuery().in(this)

uniapp中式没有window对象,和dom元素的,但是有时我们需要获取页面上节点的一些几何信息;

@touchcancel 手指触摸被打断,如来电提醒,弹窗
@touchend 手指触摸动作结束,如松开按钮
@touchmove 手指触摸后移动
@touchstart 手指触摸动作开始

3.touchmove滑动事件

@touchcancel 手指触摸被打断,如来电提醒,弹窗
@touchend 手指触摸动作结束,如松开按钮
@touchmove 手指触摸后移动
@touchstart 手指触摸动作开始

记录用户按下屏幕的坐标 x 和 y

touchmove(e) {
				// 单指触摸
				if (e.touches.length !== 1) {
					return false;
				}
				console.log('移动',e);
				this.isMove = true;

				this.left = e.touches[0].clientX - this.offsetWidth;
				let clientY = e.touches[0].clientY - this.offsetHeight;
				// #ifdef H5
				clientY += this.height;
				// #endif
				let edgeBottom = this.windowHeight - this.height - this.edge;
				// 上下触及边界
				if (clientY < this.edge) {
					this.top = this.edge;
				} else if (clientY > edgeBottom) {
					this.top = edgeBottom;
				} else {
					this.top = clientY
				//将top存入本地存储
				 uni.setStorageSync("top", this.top);
			},
			touchend(e) {
				if (this.isDock) {
					let edgeRigth = this.windowWidth - this.width - this.edge;
					if (this.left < this.windowWidth / 2 - this.offsetWidth) {
						this.left = this.edge;
					} else {
						this.left = edgeRigth;
					}
				//将left存入本地存储
				 uni.setStorageSync("left", this.left);
				this.isMove = false;
				this.$emit('btnTouchend');
		}

每次移动这个按钮,本地存储的值都会改变;

取出存储的值

onShow() {
			//获取手机信息配置接口
			const sys = uni.getSystemInfoSync();
			//屏幕的宽高
			this.windowWidth = sys.windowWidth;
			this.windowHeight = sys.windowHeight;
			// #ifdef APP-PLUS
			this.existTabBar && (this.windowHeight -= 50);
			// #endif
			if (sys.windowTop) {
				this.windowHeight += sys.windowTop;
			}
			//获取元素
			const query = uni.createSelectorQuery().in(this);
			query.select('#_drag_button').boundingClientRect(data => {
				console.log(data);
				this.width = data.width;
				this.height = data.height;
				this.offsetWidth = data.width / 2;
				this.offsetHeight = data.height / 2;
				// this.left = this.windowWidth - this.width - this.edge;
				// this.top = this.windowHeight - this.height - this.edge;
				this.left = uni.getStorageSync('left')
				this.top=uni.getStorageSync('top')
				this.$nextTick(() => {
					this.firstIn = true
				})
			}).exec();
		},

赋值

<view id="_drag_button" class="drag" :style="{top:top+'px',left:left+'px',opacity:firstIn?1:0}"
			@touchstart="touchstart" @touchmove.stop.prevent="touchmove" @touchend="touchend"
			@click.stop.prevent="click" :class="{transition: isDock && !isMove }">
			<button class="btn" open-type="contact" style="border: none;padding: 0;margin: 0;">
				<image class="img"
					src="图片地址">
				</image>
			</button>
		</view>

全局注册组件

因为我这个项目是vue3,所以注册组件的时候,不需要全局引入,

这个组件,需要在每个页面引入;
组件代码:需要换个图片就可以用了;

<template>
	<view>
		<view id="_drag_button" class="drag" :style="{top:top+'px',left:left+'px',opacity:firstIn?1:0}"
			@touchstart="touchstart" @touchmove.stop.prevent="touchmove" @touchend="touchend"
			@click.stop.prevent="click" :class="{transition: isDock && !isMove }">
			<button class="btn" open-type="contact" style="border: none;padding: 0;margin: 0;">
				<image class="img"
					src="图片地址">
				</image>
			</button>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'drag-button',
		props: {
			isDock: {
				type: Boolean,
				default: false
			},
			existTabBar: {
			}
		},
		data() {
			return {
				top: 0,
				left: 0,
				width: 0,
				height: 0,
				offsetWidth: 0,
				offsetHeight: 0,
				windowWidth: 0,
				windowHeight: 0,
				isMove: true,
				edge: 10,
				text: ' ',
				firstIn: false
		onShow() {
			//获取手机信息配置接口
			const sys = uni.getSystemInfoSync();
			//屏幕的宽高
			this.windowWidth = sys.windowWidth;
			this.windowHeight = sys.windowHeight;
			// #ifdef APP-PLUS
			this.existTabBar && (this.windowHeight -= 50);
			// #endif
			if (sys.windowTop) {
				this.windowHeight += sys.windowTop;
			//获取元素
			const query = uni.createSelectorQuery().in(this);
			query.select('#_drag_button').boundingClientRect(data => {
				console.log(data);
				this.width = data.width;
				this.height = data.height;
				this.offsetWidth = data.width / 2;
				this.offsetHeight = data.height / 2;
				// this.left = this.windowWidth - this.width - this.edge;
				// this.top = this.windowHeight - this.height - this.edge;
				this.left = uni.getStorageSync('left')
				this.top=uni.getStorageSync('top')
				this.$nextTick(() => {
					this.firstIn = true
				})
			}).exec();
		methods: {
			click() {
				this.$emit('btnClick');
			touchstart(e) {
				this.$emit('btnTouchstart');
			touchmove(e) {
				// 单指触摸
				if (e.touches.length !== 1) {
					return false;
				}
				console.log('移动',e);
				this.isMove = true;
				this.left = e.touches[0].clientX - this.offsetWidth;
				let clientY = e.touches[0].clientY - this.offsetHeight;
				// #ifdef H5
				clientY += this.height;
				// #endif
				let edgeBottom = this.windowHeight - this.height - this.edge;
				// 上下触及边界
				if (clientY < this.edge) {
					this.top = this.edge;
				} else if (clientY > edgeBottom) {
					this.top = edgeBottom;
				} else {
					this.top = clientY
				 uni.setStorageSync("top", this.top);
			touchend(e) {
				if (this.isDock) {
					let edgeRigth = this.windowWidth - this.width - this.edge;
					if (this.left < this.windowWidth / 2 - this.offsetWidth) {
						this.left = this.edge;
					} else {
						this.left = edgeRigth;
					}
				 uni.setStorageSync("left", this.left);
				this.isMove = false;
				this.$emit('btnTouchend');
		}
	}
</script>
<style lang="scss">
	.drag {
		display: flex;
		justify-content: center;
		align-items: center;
		width: 180rpx;
		height: 135rpx;
		border-radius: 50%;
		font-size: $uni-font-size-sm;
		position: fixed;
		z-index: 999999;
		&.transition {
			transition: left .3s ease, top .3s ease;
	.btn {
		background-color: transparent;
		width: 135rpx;
		height: 130rpx;
		z-index: 9999;
	button::after {
		border: none;
	.img {
		height: 100%;
		width: 100%;
</style>

页面引入:

<drag-button :isDock="true" :existTabBar="true" @btnClick="btnClick" @btnTouchstart="btnTouchstart"
			@btnTouchend="btnTouchend">

引入组件

components: {
			dragButton
		},

到此这篇关于uniapp开发小程序如何实现全局悬浮按钮的文章就介绍到这了,更多相关uniapp小程序悬浮按钮内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 手把手教你uniapp和小程序分包(图文)

    目录 一.小程序分包 二.uniapp分包小程序 分包步骤: 1.配置manifest.json 2.配置pages.json 3.分包预载配置(preloadRule) 一.小程序分包 每个使用分包小程序必定含有一个主包.所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本:而分包则是根据开发者的配置进行划分. 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示 目前小程序分包

  • uniapp 实现微信小程序全局分享的示例代码

    目录 创建全局分享内容文件 引入并全局注册该文件 自定义页面分享内容  uniapp 实现微信小程序的全局转发给好友/分享到朋友圈的功能.主要使用 Vue.js 的 全局混入 概念. 下面直接上 实现步骤和代码: 创建全局分享内容文件 1.创建一个全局分享的 js 文件.示例文件路径为:@/common/share.js ,在该文件中定义全局分享的内容: export default { data() { return { // 默认的全局分享内容 share: { title: '全局分享的标

  • 微信小程序uniapp实现左滑删除效果(完整代码)

    微信小程序uniapp实现左滑删除效果 实现效果 1,列表中侧滑删除 2,删除不同时存在 3,上下滑动与侧滑删除不影响 在本页面引入组件并使用 (文件在文章的最下方附上) 在需要左滑删除的地方使用 <view v-for="(item, index) in csListArrl" :key="index" :data-index="index"> <delSlideLeft :item="item" :dat

  • uniapp开发小程序实现全局悬浮按钮的代码

    目录 看效果 须知: 1.uni.getSystemInfoSync()获取手机的信息接口 2.uni.createSelectorQuery().in(this) 3.touchmove滑动事件 取出存储的值 赋值 全局注册组件 看效果 这是一个全局的按钮,可以换成图片,自己写样式,每个页面都有: 须知: 1.uni.getSystemInfoSync()获取手机的信息接口 可以拿到手机屏幕的宽高 2.uni.createSelectorQuery().in(this) uniapp中式没有w

  • 微信小程序使用uni-app开发小程序及部分功能实现详解

    目录 一.uni-app 1.简介 2.开发工具 3.新建 uni-app项目 4.把项目运行到微信开发者工具 二.实现tabBar效果 1.创建tabBar页面 2.配置tabBar 三.配置网络请求 1.依照官网提示安装.导入.使用 2.实战 四.uni-app 里面小程序分包 1.创建分包目录 2.在 pages.json 文件中配置 3.创建分包页面 五.公用方法封装 六.搜索功能 1.搜索组件 2.搜索建议实现 3.本地存储 4.过滤器 七.上拉加载.下拉刷新 1.上拉加载 2.下拉刷

  • uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果

    前言 实现思路:通过小程序API中的触摸事件,配合CSS来实现元素的显示和隐藏.ps(也想过另一种通过监听页面滚动的方式来实现,不过效果一定很差0.0) 一.需要用到的事件touchmove.touchend 二.话不多说上代码 1.看需求,如果是整个屏幕滑动后元素发生变化,最好放在最外面的view 代码如下: <view class="container" @touchmove="handletouchstart" @touchend="handl

  • uniapp开发小程序的经验总结

    1. 新建UI项目 首先,我们的UI是基于ColorUI,当ColorUI没有的样式,就基于Uniapp自带的UI.所以项目的开始要引入这两个UI框架. 如下,新建一个uni-ui项目. 再建立一个ColorUI项目. 如果需要观看ColorUI的效果以便直到自己需要用哪些组件,可以将其运行起来,如下. uni-ui同理.这样只要我们需要的样式都可以在这两个UI取材了. 2. 搭建自己的项目 新建一个自己的uniapp项目,建立完成后.项目结构如下. 接着先引入ColorUI样式: 将Color

  • uniapp封装小程序雷达图组件的完整代码

    效果图: 实现代码如下 view <canvas id="radar-canvas" class="radar-canvas" type="2d"></canvas> style .radar-canvas width 550rpx height 550rpx margin 0 auto script <script> import { toRpx } from "@/utils/common&quo

  • 关于uniapp微信小程序左上角返回按钮的监听详解

    目录 项目场景: 问题描述: 原因分析: 解决方案一: 解决方案二: 结语 项目场景: uni-app 开发微信小程序,界面中点击左上角的返回按钮或者是系统自带的虚拟返回操作,返回前监听用户是否在页面内进行了相应操作,如果有则进行提示(提示用户是否确定要返回),如果没有则直接返回. 问题描述: uni-app 页面生命周期中有 onBackPress ,不过不支持微信小程序.翻看微信小程序官方文档,并未发现可以监听到左上角返回按钮的事件.查阅相关技术文档,确认微信小程序现阶段并没有提供监听左上角

  • Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果

    Taro 就是可以用 React 语法写小程序的框架,拥有多端转换能力,一套代码可编译为微信小程序.百度小程序.支付宝小程序.H5.RN等 摘要: 年后入职了一家新公司,与前同事交接完之后,发现公司有一个四端的项目(iOS,Android,H5,小程序),iOS和安卓都实现了左滑右滑的效果,而h5和小程序端没实现,询问得知前同事因网上没找到对应的插件,相关博客也特别少,所以没做就搁置下来了. 趁这段时间相对来说比较富裕,于是乎在网上也搜索了一下,发现确实很少,但是有人提到可以用小程序可拖动组件m

  • 使用 UniApp 实现小程序的微信登录功能

    1.微信登录思路: 在main.js 中封装公共函数,用于判断用户是否登录 在main.js 中分定义全局变量,用于存储接口地址 如果没有登录.则跳转至登录页面 进入登录页面 通过 wx.login 获取用户的 code 通过 code 获取用户的 SessionKey.OpenId 等信息[本应后台接口.但是此处使用js发送请求] 通过 openId 调用后台 Api 获取用户的信息 获取成功,则说明已经授权过了,直接登录成功 获取失败,则说明没有授权过,需要授权之后才能进行登录 用户点击页面

  • vscode+gulp轻松开发小程序的完整步骤

    利用 gulp+vscode 来开发小程序的一个小工具,内置扩展了一系列的 wx 全局api方法,支持自定义配置相对应的信息和别名等问题 安装方法: # 全局安装 npm install -g wechat-mini-gulp # 当前小程序根目录下运行 wechat-gulp run init # 安装依赖 npm install 运行 #开发环境 npm run gulpdev #正式环境 npm run gulpbuild # 测试环境 npm run gulptest # 清空conso

  • Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码

    Taro 就是可以用 React 语法写小程序的框架,拥有多端转换能力,一套代码可编译为微信小程序.百度小程序.支付宝小程序.H5.RN等 摘要: 年后入职了一家新公司,与前同事交接完之后,发现公司有一个四端的项目(iOS,Android,H5,小程序),iOS和安卓都实现了左滑右滑的效果,而h5和小程序端没实现,询问得知前同事因网上没找到对应的插件,相关博客也特别少,所以没做就搁置下来了. 趁这段时间相对来说比较富裕,于是乎在网上也搜索了一下,发现确实很少,但是有人提到可以用小程序可拖动组件m

随机推荐