zoukankan      html  css  js  c++  java
  • vue 悬浮框 可拖动

    效果图:

    首先是样式布局:

     <div class="ys-float-btn" :style="{'width':itemWidth+'px','height':itemHeight+'px','left':left+'px','top':top+'px'}"
               ref="div"
               @click ="onBtnClicked">
            <slot name="icon"></slot>
            <image class="su_img" src="../../../static/clouddisk/icon_qiye.svg"></image>
          </div>

    第二步首次进入页面时,按钮应该处于一个初始位置。我们在created钩子中进行初始化。

    created(){
          this.left = document.documentElement.clientWidth - 50;
          this.top = document.documentElement.clientHeight*0.8;
        },

    第三步,在写一个监听事件

     mounted(){
          window.addEventListener('scroll', this.handleScrollStart);
          this.$nextTick(()=>{
            const div = this.$refs.div;
            div.addEventListener("touchstart",()=>{
              div.style.transition = 'none';
            });
            div.addEventListener("touchmove",(e)=>{
              if (e.targetTouches.length === 1) {
                let touch = event.targetTouches[0];
                this.left = touch.clientX - this.itemWidth/2;
                this.top = touch.clientY - this.itemHeight/2;
              }
            });
            div.addEventListener("touchend",()=>{
              div.style.transition = 'all 0.3s';
               if(this.left>this.clientWidth/2){
                 this.left = this.clientWidth - this.itemWidth - this.gapWidth;
               }else{
                 this.left = this.gapWidth;
               }
            });
    
          });
        },

    第四步,需要在popos里面定义初始值:

    props:{
          itemWidth:{
            type:Number,
            default:60
          },
          itemHeight:{
            type:Number,
            default:60
          },
          gapWidth:{
            type:Number,
            default:10
          },
        
          coefficientHeight:{
            type:Number,
            default:0.8
          }
        },

    第五步在对methods进行处理:

        methods:{
          onBtnClicked(){
            this.$emit("onFloatBtnClicked");
          },
      
        },

    第六步在将created里面拖动的left和top进行处理,完整代码是这样子的:

     created(){
          this.clientWidth = document.documentElement.clientWidth;
          this.clientHeight = document.documentElement.clientHeight;
          this.left = this.clientWidth - this.itemWidth - this.gapWidth;
          this.top = this.clientHeight*this.coefficientHeight;
        },

    最后补充一点,我这边因为需要,我将拖动的上下距离在mounted里面做了判断,让他拖动的时候不会超出我的头部的高度和底部的高度

    mounted(){
    this.$nextTick(()=>{
    const div = this.$refs.div;
    div.addEventListener("touchstart",(e)=>{
    e.stopPropagation();
    div.style.transition = 'none';
    });
    div.addEventListener("touchmove",(e)=>{
    e.stopPropagation();
    if (e.targetTouches.length === 1) {
    let touch = event.targetTouches[0];
    this.left = touch.clientX - this.itemWidth/2;
    this.top = touch.clientY - this.itemHeight/2;
    }
    },
    false
    );
    div.addEventListener("touchend",(e)=>{
    e.stopPropagation();
    div.style.transition = 'all 0.3s';
    if(this.left>this.clientWidth/2){
    this.left = this.clientWidth - this.itemWidth - this.gapWidth;
    }else{
    this.left = this.gapWidth;
    }
    if(this.top<=36)
    {
    this.top=36+this.gapWidth
    }
    else{
    let bottom=this.clientHeight-50-this.itemHeight-this.gapWidth
    console.log(bottom,this.top)
    if(this.top>=bottom)
    {
    this.top=bottom
    }

    }
    });
    });
    },

    如果你们没有头部和底部高度可以随意滚动就直接这样子写就行:

     mounted(){
          window.addEventListener('scroll', this.handleScrollStart);
          this.$nextTick(()=>{
            const div = this.$refs.div;
            div.addEventListener("touchstart",()=>{
              div.style.transition = 'none';
            });
            div.addEventListener("touchmove",(e)=>{
              if (e.targetTouches.length === 1) {
                let touch = event.targetTouches[0];
                this.left = touch.clientX - this.itemWidth/2;
                this.top = touch.clientY - this.itemHeight/2;
              }
            });
            div.addEventListener("touchend",()=>{
              div.style.transition = 'all 0.3s';
               if(this.left>this.clientWidth/2){
                 this.left = this.clientWidth - this.itemWidth - this.gapWidth;
               }else{
                 this.left = this.gapWidth;
               }
            });
    
          });
        },

    最后我直接就完整代码:

    <template>
         <div class="ys-float-btn" :style="{'width':itemWidth+'px','height':itemHeight+'px','left':left+'px','top':top+'px'}"
               ref="div"
               @click ="onBtnClicked">
            <slot name="icon"></slot>
            <image class="su_img" src="../../../static/clouddisk/icon_qiye.svg"></image>
          </div>
    </template>
    
    
    <script>
      export default {
        name: "FloatImgBtn",
        props:{
          itemWidth:{
            type:Number,
            default:60
          },
          itemHeight:{
            type:Number,
            default:60
          },
          gapWidth:{
            type:Number,
            default:10
          },
        
          coefficientHeight:{
            type:Number,
            default:0.8
          }
        },
        created(){
          this.clientWidth = document.documentElement.clientWidth;
          this.clientHeight = document.documentElement.clientHeight;
          this.left = this.clientWidth - this.itemWidth - this.gapWidth;
          this.top = this.clientHeight*this.coefficientHeight;
        },
        mounted(){
          this.$nextTick(()=>{
            const div = this.$refs.div;
            div.addEventListener("touchstart",(e)=>{
                    e.stopPropagation();
              div.style.transition = 'none';
            });
            div.addEventListener("touchmove",(e)=>{
                    e.stopPropagation();
              if (e.targetTouches.length === 1) {
                let touch = event.targetTouches[0];
                this.left = touch.clientX - this.itemWidth/2;
                this.top = touch.clientY - this.itemHeight/2;
              }
            },
            false
            );
            div.addEventListener("touchend",(e)=>{
                e.stopPropagation();
              div.style.transition = 'all 0.3s';
               if(this.left>this.clientWidth/2){
                 this.left = this.clientWidth - this.itemWidth - this.gapWidth;
               }else{
                 this.left = this.gapWidth;
               }
               if(this.top<=36)
               {
                   this.top=36+this.gapWidth
               }
               else{
                   let bottom=this.clientHeight-50-this.itemHeight-this.gapWidth
                   console.log(bottom,this.top)
                   if(this.top>=bottom)
                   {
                       this.top=bottom
                   }
    
               }
            });
          });
        },
    
        methods:{
          onBtnClicked(){
            this.$emit("onFloatBtnClicked");
          },
      
        },
        data(){
          return{
            timer:null,
            currentTop:0,
            clientWidth:0,
            clientHeight:0,
            left:0,
            top:0,
          }
        }
      }
    </script>
    
    
    
    <style lang="scss" scoped>
        .ys-float-btn{
            background:rgba(56,181,77,1);
            box-shadow:0 2px 10px 0 rgba(0,0,0,0.1);
            border-radius:50%;
            color: #666666;
            z-index: 20;
            transition: all 0.3s;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            position: fixed;
            bottom: 20vw;
        
            img{
               50%;
              height: 50%;
              object-fit: contain;
              margin-bottom: 3px;
            }
          }
    .su_img{
                 40px;
                height: 40px;
                margin: 8px 0 0 0;
        }
    
    </style>
  • 相关阅读:
    CSS和Js样式属性的对照关系
    CSS选择器
    主成分分析(PCA)核心思想
    线性变换的本质
    java 滤镜实现
    Spring Boot工程发布到Docker
    解决maven的报错
    spring boot初探
    WPF的Page介绍及Page Window Frame 之间的链接使用示例,嵌套问题
    浅谈WPF页间导航
  • 原文地址:https://www.cnblogs.com/lovebear123/p/12836931.html
Copyright © 2011-2022 走看看