Узнайте, как перетащить элемент из его div в другой div

Vue.js jQuery

предыстория истории:

Получен новый спрос, требуется VUE, в основном перетаскивание макета реализации, ключевые моменты:Перетаскивание одного компонента, перетаскивание компонента в одной строке и нескольких столбцах,Один компонент можно перетащить в строку и несколько столбцов., Перетаскивание одного компонента легко осуществить, главное перетащить компонент на другой, похожий на таблицу, а в некоторых случаях необходимо ограничитьПеретаскивание возможно только по горизонталиЯ собирал данные сами, экспериментировал и, наконец, придумал это.

Принцип в основном делится на две категории:

  1. HTML5 поставляется с API перетаскивания, доступные библиотеки:Vue.Draggable  
  2. Используйте js для отслеживания положения мыши. Доступны следующие библиотеки: jquery ui
  3. Использовать точечное событие: нет (подробнее об этом ниже)

Недостатки каждого

Недостаток перетаскивания 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 может относиться сюда:

у-у-у-у. palms.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, вы можете сначала посмотреть на него. здесь  

Посмотрите на следующий код:

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

Ключевой вопрос перед тем, как судить о перетаскиваемом элементе$( "#draggable" ) Когда вы вошли в место, которое можно разместить?$( "#droppable" ) Да глядя на исходники его реализация просто тащит$( "#draggable" ) Следите за положением мыши, когда$( "#droppable" )Информация о положении области , пока мышь входит в область, она будет срабатывать.

Следуя этой мысли, проведение экспериментов может хорошо удовлетворить ваши собственные потребности!

Эффект реализации демо выглядит следующим образом:


Кодовый адрес: https://github.com/YalongYan/vue-drag-layout

Должна быть лучшая реализация макета перетаскивания, и вы можете предложить лучшие реализации.