可自由拖动的自定义组件

效果图:

效果图

基本思路

通过监听组件touch事件,来改变组件的left和top的样式

1.首先,touchstart时,拿到组件初始状态时的位置

2.touchmove,实时拿到组件的位置,并修改组件的left和top的值

3.如果要求吸附到旁边,在touchend时,看最后组件的位置是偏向于左边还是右边,如果偏向于左边,left设置为0,否则就是可移动的最大屏幕宽距

 

代码

drag.js

var template = `
<div id="default_drag_comp"
  @touchstart="down"
  @touchmove="move"
  @touchend="end"
>
  <span>拖我移动看看</span>
</div>
`
Vue.component('drag-comp', {
    template: template,
    data() {
        return {
            flags: false,
            position: {
                x: 0,
                y: 0
            },
            nx: "", // 移动后,组件的x轴位置
            ny: "",
            dx: "", //初始状态时,组件的位置
            dy: "",
        }
    },
    props: {
        isStiky: Boolean
    },
    methods: {
        // 实现移动端拖拽
        down() {
            let default_drag_comp = document.querySelector("#default_drag_comp");
            this.flags = true;
            var touch;
            if (event.touches) {
                touch = event.touches[0];
            } else {
                touch = event;
            }
            console.log(touch.clientX);
            console.log(touch.clientY);
            
            this.maxW = document.body.clientWidth - default_drag_comp.offsetWidth;
            this.maxH = document.body.clientHeight - default_drag_comp.offsetHeight;
            this.position.x = touch.clientX - default_drag_comp.offsetLeft;
            this.position.y = touch.clientY - default_drag_comp.offsetTop;
            this.dx = touch.clientX;
            this.dy = touch.clientY;
        },
        move(event) {
            event.preventDefault();
            let default_drag_comp = document.querySelector("#default_drag_comp");
            if (this.flags) {
                var touch;
                if (event.touches) {
                    touch = event.touches[0];
                } else {
                    touch = event;
                }
                this.nx = touch.clientX - this.position.x;
                this.ny = touch.clientY - this.position.y;

                if (this.nx < 0) {
                    this.nx = 0;
                } else if (this.nx > this.maxW) {
                    this.nx = this.maxW;
                }

                if (this.ny < 0) {
                    this.ny = 0;
                } else if (this.ny >= this.maxH) {
                    this.ny = this.maxH;
                }
                default_drag_comp.style.left = this.nx + "px";
                default_drag_comp.style.top = this.ny + "px";
                //阻止页面的滑动默认事件;如果碰到滑动问题,1.2 请注意是否获取到 touchmove
                document.addEventListener(
                    "touchmove",
                    function () {
                        // event.preventDefault();
                    },
                    false
                );
            }
        },
        //鼠标释放时候的函数
        end() {
            let default_drag_comp = document.querySelector("#default_drag_comp");
            if (this.isStiky) {
                if (this.nx > this.maxW / 2) {
                    // 右边
                    this.nx = this.maxW
                    default_drag_comp.style.left = this.nx + "px";
                } else {
                    // 左边
                    this.nx = 0
                    default_drag_comp.style.left = this.nx + "px";
                }
            }
            this.flags = false;
        }
    }
});
<script src="__static__/common/script/drag.js"></script>

 <div id="app">
   <div class="area aui-text-center aui-padded-t-15">
     <div>是否可吸附至左右两侧</div>
     <div style="display: flex; flex-direction: row; align-items: center; justify-content: space-around;margin-top: 20px;">
       <div class="btn" :class="isStiky?'active':''" @click="isStiky=true">是</div>
       <div class="btn" :class="isStiky?'':'active'" @click="isStiky=false">否</div>
     </div>
     <drag-comp :is-stiky="isStiky" />
   </div>
</div>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      isStiky:false
    },
    methods: {

    },
    mounted: function () {

    }
  });
</script>
 html,
  body,
  #app {
    height: 100%;
    background-color: #ffffff;
  }

  #default_drag_comp {
    width: 56px;
    height: 56px;
    padding:3px;
    border-radius: 50%;
    border: 2px solid #ffffff;
    box-shadow: 0 0 10px 2px #d3d3d3;
    background: #ff9966;
    position: fixed;
    z-index: 1000;
    bottom: 66px;
    right: 8px;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  #default_drag_comp span {
    color: #ffffff;
    font-size: 12px;
  }
  .btn{
    width: 30%;
    padding: 3px 5px;
    border: 1px solid;
    border-radius: 5px;
  }
  .active{
    color: red;
  }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值