需求:
1. 每个页面都能自动加上悬浮按钮
2. 可拖拽
3. 点击返回首页
效果图:
方式一:js原生写法:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let div = document.createElement('div'); let clientWidth = document.documentElement.clientWidth // 获取手机的像素宽度 let clientHeight = document.documentElement.clientHeight// 获取手机的像素高度 div.style.boxShadow = '0px 0px 0px 0.5em #e0e1e9' ; div.style.width = "24px"; div.style.height = "24px"; div.style.left = clientWidth - 50+'px'; console.log("初始位置left"+div.style.left) div.style.top = clientHeight * 0.6+'px'; div.style.zIndex = '100000'; div.style.position= 'fixed'; div.style.background = 'red'; div.style.transition='all 0.3s'; div.style.bottom='436px'; div.style.right= 0; div.style.margin='5px 10px'; div.style.background='rgb(197 203 211)' div.style.borderRadius = '15px'; document.body.appendChild(div); var divattr = document.createAttribute("id"); divattr.value = "float_info"; //把属性id = "float_info"添加到div div.setAttributeNode(divattr); let flag = 0; //标记是拖曳还是点击 var oDiv = document.getElementById('float_info'); oDiv.style.display = 'block'; // 显示元素 oDiv.addEventListener("touchstart", () => { flag = 0; oDiv.style.transition = 'none' }) // 在拖拽的过程中,按钮应该跟随鼠标的移动而移动。 oDiv.addEventListener("touchmove", (e) => { flag=1 console.log('移动中', e) if (e.targetTouches.length === 1) { // 一根手指 e.preventDefault();// 阻止默认的滚动行为 div.style.left = e.targetTouches[0].clientX-20 +'px'//clientX:触摸目标在视口中的x坐标。 div.style.top = e.targetTouches[0].clientY -25 +'px'//clientY:触摸目标在视口中的y坐标。 console.log('移动中', div.style.left) } }) // 拖拽结束以后,重新调整按钮的位置并重新设置过度动画。 oDiv.addEventListener("touchend", () => { // 如果是点击跳转到首页 if(flag==0){ that.$router.push({ path: "/workspaces/views/index/index", }); }else { div.style.transition = 'all 0.3s' console.log('拖拽结束后left', div.style.left) console.log('拖拽结束后top', div.style.top) if ( parseInt(div.style.left)> (document.documentElement.clientWidth / 2)) { div.style.left = document.documentElement.clientWidth -50+'px'; } else { div.style.left = 0+'px' } // 控制其超出屏幕回到原始位置 if ( parseInt(div.style.top)> (document.documentElement.clientHeight)|| parseInt(div.style.top)<0) { div.style.top = document.documentElement.clientHeight* 0.6+'px' } } }) </script> </body> </html>
复制
注:如果想在vue项目中的每个页面都加上悬浮按钮,可用js,写在APP.vue的onLaunch()函数里
方式二:
1.创建一个FloatingButton.vue的组件
<template> <!-- 子组件 --> <div class="float_button"> <div @click="onBtnClicked" ref="floatButton" class="float_info" :style="{'width': itemWidth + 'px','margin':'5px 10px', 'height': itemHeight + 'px', 'left': left + 'px', 'top': top + 'px'}" > <span class="text">返回首页</span> </div> </div> </template> <script> export default { data() { return { clientWidth: 0, clientHeight: 0, timer: null, currentTop: 0, left: 0, top: 0, itemWidth: 70 , //按钮宽度 isShort: true, itemHeight: 32, // 悬浮按钮高度 gapWidth: 0, // 距离左右两边距离 coefficientHeight: 0.6, // 从上到下距离比例 } }, props: { }, computed: { }, created() { // console.log('屏幕宽度', document.documentElement.clientWidth) // console.log('屏幕高度度', document.documentElement.clientHeight) let type = navigator.userAgent; // console.log('设备', type) this.clientWidth = document.documentElement.clientWidth this.clientHeight = document.documentElement.clientHeight this.left = this.clientWidth - this.itemWidth - this.gapWidth - 20; this.top = this.clientHeight * this.coefficientHeight }, watch: { left(n, o) { } }, methods: { onBtnClicked() { }, handleScrollStart() { console.log('这是啥时候触发呀?ScrollStart') this.timer && clearTimeout(this.timer) this.timer = setTimeout(() => { this.handleScrollEnd() }, 300) this.currentTop = document.documentElement.scrollTop || document.body.scrollTop if (this.left > this.clientWidth / 2) { this.left = this.clientWidth - this.itemWidth / 2 } else { this.left = -this.itemWidth / 2 } }, handleScrollEnd() { let scrollTop = document.documentElement.scrollTop || document.body.scrollTop if (scrollTop === this.currentTop) { if (this.left > this.clientWidth / 2) { this.left = this.clientWidth - this.itemWidth - this.gapWidth } else { this.left = this.gapWidth } clearTimeout(this.timer) } }, }, mounted() { this.$nextTick(() => { const floatButton = this.$refs.floatButton floatButton.addEventListener("touchstart", () => { floatButton.style.transition = 'none' }) // 在拖拽的过程中,组件应该跟随手指的移动而移动。 floatButton.addEventListener("touchmove", (e) => { // console.log('移动中', e) if (e.targetTouches.length === 1) { // 一根手指 document.body.addEventListener('touchmove', this.bodyScroll, { passive: false }); //禁止页面滑动 let touch = e.targetTouches[0] this.left = touch.clientX - 20 this.top = touch.clientY - 25 } }) // 拖拽结束以后,重新调整组件的位置并重新设置过度动画。 floatButton.addEventListener("touchend", () => { floatButton.style.transition = 'all 0.3s' console.log('拖拽结束后left', this.left) document.body.removeEventListener('touchmove', this.bodyScroll, { passive: false }); //解除页面禁止滑动 if (this.left > document.documentElement.clientWidth / 2) { this.left = document.documentElement.clientWidth - this.itemWidth - 20; } else { this.left = 0 } }) }) }, beforeDestroy() { // 添加监听页面滚动 window.removeEventListener('scroll', this.handleScrollStart) }, destroyed() { } } </script> <style lang="scss" scoped> .float_button { .float_info { box-shadow: #1666ca; transition: all 0.3s; position: fixed; bottom: 436px; right: 0; margin: 5px 10px; display: flex; flex-flow: row; justify-content: center; align-items: center; z-index: 999; background: #1666ca; background-color: rgba(22, 102, 202, 0.6); border-radius: 10px; cursor: pointer; .text { font-size: 12px; color: #fff; } } } </style>
复制
2.然后在main.js中注册全局组件(这里大家根据自己的实际路径替换)
import FloatingButton from '@/workspaces/tools/FloatingButton.vue'; Vue.component('FloatingButton', FloatingButton)
复制
3.最后在需要这个悬浮按钮的页面模板中用这个组件就可以了
<FloatingButton/>
复制