探讨把一个元素从它所在的div 拖动到另一个div内的实现方法

栏目: jQuery · 发布时间: 5年前

内容简介:接到一个新需求,要求用vue搞,主要是拖动实现布局,关键点有H5拖动的缺点:不能限制在水平 或垂直方向上拖动。使用原生js缺点:大量的dom操作,代码复杂(jquery ui 封装的比较好了,可直接用)

故事背景:

接到一个新需求,要求用vue搞,主要是拖动实现布局,关键点有 单个组件拖动,一行多列里面的组件拖动,  单个组件可以拖入一行多列里 , 单个组件的拖动好实现,关键是把一个组件拖动到另一个类似于表格里面,而且有的情况下还需要限制 拖动只能在水平方向 ,自己搜集资料, 实验,终于搞出来了。

原理上主要分为两类:

  1. HTML5自带的拖放api,可用的库有 :  Vue.Draggable   
  2. 使用js 监听鼠标的移动位置, 可用的库有:  jquery ui
  3. 使用point-event: none(下面会详细说明)

各自缺点

H5拖动的缺点:不能限制在水平 或垂直方向上拖动。

使用原生js缺点:大量的dom操作,代码复杂(jquery ui 封装的比较好了,可直接用)

但是问题来了,这次的需求是把基于jquery ui 的拖动 用 vue 重构,那么用vue.draggable吧, 但是需求里正好有一条是要限制在水平方向上拖动,尴尬,用不了。

寻找方案

最开始的尝试:

<!DOCTYPE html>
<html>
<head>
	<title>vue结合原生js实现拖动</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="ctn ctn1">
	<div class="sub sub1" v-for="(site, index) in list1">
   	  <div class="dragCtn fixed" :style="{ left: X+'px', top: Y+'px'}"
           @mousedown="mousedown(site, $event)"
           @mousemove.prevent='mousemove(site, $event)'
           @mouseup='mouseup(site, $event)'>
   	  	拖动我
   	  </div>
   </div>
</div>

<div class="ctn ctn2">
	<div class="sub sub2" v-for="(site, index) in list2"
          @mouseenter='mouseenter(site, $event)'>
   	  <div class="dragCtn">
   	  	{{ index }} : {{ site.name }}
   	  </div>
   </div>
</div>
   
</div>

<script>
new Vue({
  el: '#app',
  data: {
    list1: [{name:1, index:0}],
    list2: [{name:'a', index:0}, {name:'b', index:1}, {name:'c', index: 2}, {name:'d', index: 3}],
    vm:'',
    sb_bkx: 0,
    sb_bky: 0,
    is_moving: false,
    X: 0,
    Y: 0
  },
  methods: {
  	mousedown: function (site, event) {
		var startx=event.x;
		var starty=event.y;
		this.sb_bkx=startx - event.target.offsetLeft;
		this.sb_bky=starty - event.target.offsetTop;
		this.is_moving = true;
  	},
  	mousemove: function (site, event) {
  		var endx=event.x - this.sb_bkx;
		  var endy=event.y - this.sb_bky;
		  var _this = this
		  if(this.is_moving){
	    	this.X = endx;
	    	this.Y = endy;
      }
  	},
  	mouseup: function (e) {
  	  this.is_moving = false;
  	},
    mouseenter: function (){
      console.log('鼠标进入')
    }
  }
})
</script>

<style>
    .ctn{
    	line-height: 50px;
    	cursor: pointer;
    	font-size: 20px;
    	text-align: center;
    	float: left;
    }
    .sub:hover{
        background: #e6dcdc;
        color: white;
        width: 100px;
    }
   	.ctn1{
   		border: 1px solid green;
   		width: 100px;
   	}
   	.ctn2{
   		border: 1px solid black;
   		width: 100px;
   		margin-left: 50px;
   	}
   	.fixed{
   	  width: 100px;
      position: fixed;
      background: red;
      left: 0;
      top: 0;
      cursor: move;
   	}
</style>
</body>
</html>
复制代码

就这样实现了基本的拖动,但是在拖动的时候,就不能触 mouseenter   事件了,而且鼠标必须拖动的很慢,移动快一点,拖动的div就跟不上了,这一点到现在还困惑,希望各位大侠指点。然后在网上找了很多资料,类库,但是不能完全符合我的需求,于是准备自己写了;

首先是给组件添加mousedown事件,然后mousemove的时候 监听鼠标的位置,再赋值给组件,实现拖动,但是当组件拖动进入另一个元素的时候,无法监听mouseenter, 后来想的办法是给正在拖动的组件加上 point-event:none 属性,就是消除原有的鼠标事件,就可以触发其他组件的mouerenter事件了,point-event 属性的具体用法 可以参考这里:

www.zhangxinxu.com/wordpress/2…

因为拖动是用原生js写的,所以可以限制在水平方向拖动,再加上可以触发mouseenter事件,就正好实现的我的需求。

伪代码如下:

mousedown: function (event, site) {        document.onmousemove=function (ev) {          // 移动的时候给元素增加 point-event:none 属性           
           ...        }        document.onmouseup=function (ev) {
           // up的时候 要移除point-event属性
           ...         }    }复制代码

但是后来上面要求,要兼容ie10,由于  point-event:none 是H5的属性,于是我赶紧去看看兼容性, 可怕的事发生了, point-event 属性只兼容到 ie11 ,完蛋!

再想其他办法吧,没了思路,老版本的拖动是基于 jquery ui  的 ,于是去看了 jquery ui 的源码,看看它的拖动是怎么实现的。

jquery ui 拖动实现原理

不熟悉 jquery ui 的拖动方法的可以先看下 这里

看下面这段代码:

$(function() {
    $( "#draggable" ).draggable();
    $( "#droppable" ).droppable({
      drop: function( event, ui ) {
        $( this ).html( "Dropped!" );
      }
    });
  });复制代码

之前的关键问题就是怎么判断拖动的元素 $( "#draggable" )  在什么时候 进入了可以放置的区域       $( "#droppable" )  的,看了源码,它的实现方式 简单来说就是拖动   $( "#draggable" )  的时候监听 鼠标的位置, 同时获取   $( "#droppable" ) 的区域位置信息,只要鼠标进入该区域,就触发。

顺着这个思路,做了实验 可以满足自己的需求 good !

demo的实现效果如下:

探讨把一个元素从它所在的div 拖动到另一个div内的实现方法

代码地址:  https://github.com/YalongYan/vue-drag-layout

拖动布局的实现方式应该还有更好的,欢迎大家提出更好的实现方式。


以上所述就是小编给大家介绍的《探讨把一个元素从它所在的div 拖动到另一个div内的实现方法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机网络(第6版)

计算机网络(第6版)

[美] James F.Kurose、[美] Keith W.Ross / 陈鸣 / 机械工业出版社 / 2014-10 / 79.00元

《计算机网络:自顶向下方法(原书第6版)》第1版于12年前出版,首创采用自顶向下的方法讲解计算机网络的原理和协议,出版以来已被几百所大学和学院选用,是业界最经典的计算机网络教材之一。 《计算机网络:自顶向下方法(原书第6版)》第6版继续保持了以前版本的特色,为计算机网络教学提供了一种新颖和与时俱进的方法,同时也进行了相当多的修订和更新:第1章更多地关注时下,更新了接入网的论述;第2章用pyt......一起来看看 《计算机网络(第6版)》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具