实际样式,可以实现悬浮贴边,同时可以拖动,自动贴边
图片下方带文字,可以根据自己的需求更改样式。可以全局任意页面存在
可以全局实现一个悬浮按钮,同时按钮可以点开,再次排列图标提供点击操作事件
代码内容
import from '@/static/image/'
//上面的内容为引入的图片等内容
//下面部分为设置的默认样式,可以在main.js文件内传入相关内容,下面的参数根据需要删改
const defaultOptions = {
url: '',
isStickySide: false,
isUni: true,
stickyLeft: false,
stickyRight: false,
vertical: true,
horizontal: true,
style: {
width: '140rpx',
height: '80rpx',
top: '1160rpx',
right: '0',
zIndex: 998,
},
};
//为了便于维护,做了一个列表来方路径和图标,其他参数看着加
const listData = [{HttpPath:true,url:'网络连接地址',imageSrc:'更换图片',text:'文字',id:0},{HttpPath:true,url:'',imageSrc:'',text:'',id:1},{HttpPath:false,page:'这是页面内的代码路径',imageSrc:'',text:'',id:2},]
//使用的方法,外面就使用这个名称,下面就是不断的对样式做修改
export class Buttons {
constructor(options = defaultOptions) {
this.options = options;
this.touchStartX = 0;
this.touchStartY = 0;
this.offsetX = 0;
this.offsetY = 0;
this.isDragging = false;
this.vertical = false;
this.horizontal = false;
const { isUni, style = {}, isStickySide, stickyLeft = false, stickyRight = false, vertical = true, horizontal = true } = options;
let { width = '48px', height = '48px', background = `white`, top = '1160rpx', right = '6px', zIndex = 998 } = style;
// if (!isUni) {
// width = `${rpx2px(width)}px`;
// height = `${rpx2px(height)}px`;
// top = `${rpx2px(top)}px`;
// }
this.el = document.createElement('div');
this.el.classList.add('global-float-btn');
this.el.id = 'globalFloatBtn';
this.el.style.position = 'fixed';
this.el.style.top = top;
this.el.style.right = right;
this.el.style.zIndex = `${zIndex}`;
this.el.style.width = width;
this.el.style.height = height;
this.el.style.borderRadius = '50%'
this.el.style.display = 'flex';
this.el.style.flexDirection = 'column';
this.el.style.justifyContent = 'center';
this.el.style.alignItems = 'center';
this.el.style.background = background;
this.el.style.backgroundSize = `${width} ${height}`;
this.vertical = vertical;
this.horizontal = horizontal;
if (isStickySide || stickyLeft || stickyRight) {
this.vertical = true;
this.horizontal = true;
}
this.el.addEventListener('touchstart', this.touchstart.bind(this));
this.el.addEventListener('touchmove', this.touchmove.bind(this));
this.el.addEventListener('touchend', this.touchend.bind(this));
document.body.appendChild(this.el);
let imgElement = document.createElement('img');
imgElement.src = chevronRight
imgElement.id = 'chevronRight';
imgElement.style.width = '30px'
imgElement.style.height = '30px'
this.el.appendChild(imgElement);
}
//点击的时候的执行事件,由于是一个悬浮按钮,点击后弹出其他的悬浮按钮,所以做了点击判断
btnClick(e) {
if(e.target.id && e.target.id === 'chevronRight'){
let listDiv = document.querySelector('#globalFloatList');
if(listDiv !== null) {
listDiv.remove();
} else {
let listDiv = document.createElement('div');
listDiv.classList.add('global-float-list');
listDiv.id = 'globalFloatList';
listDiv.style.position = 'absolute';
listDiv.style.top = `-63px`;
listDiv.style.right = `60px` ;
listDiv.style.zIndex = 999;
listDiv.style.width = '48px';
listDiv.style.height = 'auto';
listDiv.style.background = 'transparent';
listDiv.style.display = 'flex';
listDiv.style.flexDirection = 'column';
listDiv.style.justifyContent = 'center';
listDiv.style.alignItems = 'center';
this.el.appendChild(listDiv);
for (let i = 0; i < listData.length; i++) {
let div = document.createElement('div');
div.style.display = 'flex';
div.style.flexDirection = 'column';
div.style.justifyContent = 'center';
div.style.alignItems = 'center';
let imgElement = document.createElement('img');
imgElement.src = listData[i].imageSrc
imgElement.id = listData[i].id;
imgElement.style.width = '40px'
imgElement.style.height = '40px'
imgElement.style.marginBottom = '3px'
div.style.marginBottom = '15px'
div.appendChild(imgElement);
let divElement = document.createElement('div');
divElement.style.height = '12px'
divElement.style.fontSize = '12px'
divElement.textContent = listData[i].text
div.appendChild(divElement);
listDiv.appendChild(div);
}
}
}else{
if(e.target.id && listData[e.target.id]){
if(listData[e.target.id].HttpPath){
if (eh.env.platform !== 'notInEhApp') {
eh.biz.util.openLink({ url: listData[e.target.id].url });
}
else if (env.platform !== 'notInDingTalk') {
biz.util.openLink({ url: listData[e.target.id].url });
}
else {
window.open(listData[e.target.id].url, '_blank');
}
}else{
uni.navigateTo({
url: `${listData[e.target.id].page}`,
})
}
let listDiv = document.querySelector('#globalFloatList');
listDiv.remove();
}
}
}
touchstart(event) {
// 阻止默认事件(防止页面滚动)
event.preventDefault();
// 计算偏移量
const touch = event.touches[0];
const touchStartX = touch.clientX;
const touchStartY = touch.clientY;
this.touchStartX = touchStartX;
this.touchStartY = touchStartY;
this.offsetX = touchStartX - this.el.offsetLeft;
this.offsetY = touchStartY - this.el.offsetTop;
// 标记正在拖动
this.isDragging = false;
}
touchmove(event) {
// 阻止默认事件(防止页面滚动)
event.preventDefault();
// 计算元素的新位置
const touch = event.touches[0];
const curTouchStartX = touch.clientX;
const curTouchStartY = touch.clientY;
const distanceX = curTouchStartX - this.touchStartX;
const distanceY = curTouchStartY - this.touchStartY;
// 大于10像素就算他拖动吧
if (Math.abs(distanceX) > 10 || Math.abs(distanceY) > 10) {
this.isDragging = true;
}
let left = this.horizontal ? touch.clientX - this.offsetX : this.el.offsetLeft;
let top = this.vertical ? touch.clientY - this.offsetY : this.el.offsetTop;
// 对元素位置进行范围限制
if (left < 0) {
left = 0;
}
else if (left > window.innerWidth - this.el.offsetWidth) {
left = window.innerWidth - this.el.offsetWidth;
}
if (top < 0) {
top = 0;
}
else if (top > window.innerHeight - this.el.offsetHeight) {
top = window.innerHeight - this.el.offsetHeight;
}
// 设置元素新的位置
this.el.style.left = `${left}px`;
this.el.style.top = `${top}px`;
}
touchend(event) {
event.preventDefault();
event.stopPropagation();
// 是拖动再做拖动该做的事情,否则做点击做的事情
if (this.isDragging) {
if (this.options.isStickySide) {
if (this.el.offsetLeft > window.innerWidth / 2 - this.el.offsetWidth) {
this.el.style.left = (window.innerWidth - this.el.offsetWidth) + "px";
}
else {
this.el.style.left = "0px";
}
}
if (this.options.stickyLeft) {
this.el.style.left = "0px";
}
if (this.options.stickyRight) {
this.el.style.left = (window.innerWidth - this.el.offsetWidth) - 6 + "px";
}
}
else {
this.btnClick(event);
}
}
destroy() {
this.el.removeEventListener('touchstart', this.touchstart.bind(this));
this.el.removeEventListener('touchmove', this.touchmove.bind(this));
this.el.removeEventListener('touchend', this.touchend.bind(this));
document.body.removeChild(this.el);
this.el = null;
}
}
在main.js使用
//直接引入,注意路径和名称
import { Buttons } from '';
// New一个后,页面就可以使用了,只是初始化了页面为位置
new Buttons({stickyRight:true,style:{
top:'60vh',
}})