简体   繁体   中英

Drag and drop grid with push effect

I am trying to integrate into my project a grid drag 'n drop functionality. I know there are many frameworks out there that does just what I want. The most popular is probably JQuery UI's sortable library .

I'm looking for one that is pure JavaScript. One that is hackable, easy to understand code. Not a whole long book of code.
I did a lot of searching, and I finally came up with this codepen which is just what I'm looking for.

The only problem I have with that is, I want the dragged element to push the others out of the way. Something like this effect:

在此输入图像描述

Notice in the above gif, item 1 doesn't get replaced with item 4, everything moves up when you drag item 1. Hope this is clear.

In the codepen , how can I make the push effect?

 function DragNSort(config) { this.$activeItem = null; this.$container = config.container; this.$items = this.$container.querySelectorAll('.' + config.itemClass); this.dragStartClass = config.dragStartClass; this.dragEnterClass = config.dragEnterClass; } DragNSort.prototype.removeClasses = function() { [].forEach.call(this.$items, function($item) { $item.classList.remove(this.dragStartClass, this.dragEnterClass); }.bind(this)); }; DragNSort.prototype.on = function(elements, eventType, handler) { [].forEach.call(elements, function(element) { element.addEventListener(eventType, handler.bind(element, this), false); }.bind(this)); }; DragNSort.prototype.onDragStart = function(_this, event) { _this.$activeItem = this; this.classList.add(_this.dragStartClass); event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.setData('text/html', this.innerHTML); }; DragNSort.prototype.onDragEnd = function(_this) { this.classList.remove(_this.dragStartClass); }; DragNSort.prototype.onDragEnter = function(_this) { this.classList.add(_this.dragEnterClass); }; DragNSort.prototype.onDragLeave = function(_this) { this.classList.remove(_this.dragEnterClass); }; DragNSort.prototype.onDragOver = function(_this, event) { if (event.preventDefault) { event.preventDefault(); } event.dataTransfer.dropEffect = 'move'; return false; }; DragNSort.prototype.onDrop = function(_this, event) { if (event.stopPropagation) { event.stopPropagation(); } if (_this.$activeItem !== this) { _this.$activeItem.innerHTML = this.innerHTML; this.innerHTML = event.dataTransfer.getData('text/html'); } _this.removeClasses(); return false; }; DragNSort.prototype.bind = function() { this.on(this.$items, 'dragstart', this.onDragStart); this.on(this.$items, 'dragend', this.onDragEnd); this.on(this.$items, 'dragover', this.onDragOver); this.on(this.$items, 'dragenter', this.onDragEnter); this.on(this.$items, 'dragleave', this.onDragLeave); this.on(this.$items, 'drop', this.onDrop); }; DragNSort.prototype.init = function() { this.bind(); }; // Instantiate var draggable = new DragNSort({ container: document.querySelector('.drag-list'), itemClass: 'drag-item', dragStartClass: 'drag-start', dragEnterClass: 'drag-enter' }); draggable.init(); 
 .drag-list { overflow: hidden; margin: 10px auto; width: 500px; border: 1px solid #ccc; } .drag-item { float: left; padding: 50px 20px; width: 25%; text-align: center; color: #555; background: #ddd; border: 1px solid #ccc; box-sizing: border-box; transition: 0.25s; } .drag-start { opacity: 0.8; } .drag-enter { opacity: 0.5; transform: scale(0.9); } 
 <div class="drag-list"> <div draggable="true" class="drag-item">A</div> <div draggable="true" class="drag-item">B</div> <div draggable="true" class="drag-item">C</div> <div draggable="true" class="drag-item">D</div> <div draggable="true" class="drag-item">E</div> <div draggable="true" class="drag-item">F</div> <div draggable="true" class="drag-item">G</div> <div draggable="true" class="drag-item">H</div> <div draggable="true" class="drag-item">I</div> <div draggable="true" class="drag-item">J</div> <div draggable="true" class="drag-item">K</div> <div draggable="true" class="drag-item">L</div> </div> 

  $(function() { $( "#sortable" ).sortable(); $( "#sortable" ).disableSelection(); }); 
  #sortable { list-style-type: none; margin: 0; padding: 0; width: 60%;cursor:move; } #sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: 18px; } #sortable li span { position: absolute; margin-left: -1.3em; } 
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <link rel="stylesheet" href="/resources/demos/style.css"> <ul id="sortable"> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 1</li> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 2</li> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 3</li> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 4</li> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 5</li> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 6</li> <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-ns"></span>Item 7</li> </ul> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM