首页 前端知识 页面悬浮按钮可拖动实现(vue和js写法)

页面悬浮按钮可拖动实现(vue和js写法)

2024-05-23 20:05:53 前端知识 前端哥 686 436 我要收藏

需求:

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/>

 

转载请注明出处或者链接地址:https://www.qianduange.cn//article/9172.html
标签
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!