1. Introduction Drag-and-drop sorting should be familiar to everyone. When working normally, you may choose to use open source libraries such as 2. Implementation{ margin: 0; padding: 0; box-sizing: border-box; } .grid { display: flex; flex-wrap: wrap; margin: 0 -15px -15px 0; touch-action: none; user-select: none; } .grid-item { width: 90px; height: 90px; line-height: 88px; text-align: center; margin: 0 15px 15px 0; background: #FFF; border: 1px solid #d6d6d6; list-style: none; } .active { background: #c8ebfb; } .clone-grid-item { position: fixed; left: 0; top: 0; z-index: 1; width: 90px; height: 90px; line-height: 88px; text-align: center; background: #FFF; border: 1px solid #d6d6d6; opacity: 0.8; list-style: none; } <ul class="grid"> <li class="grid-item">item1</li> <li class="grid-item">item2</li> <li class="grid-item">item3</li> <li class="grid-item">item4</li> <li class="grid-item">item5</li> <li class="grid-item">item6</li> <li class="grid-item">item7</li> <li class="grid-item">item8</li> <li class="grid-item">item9</li> <li class="grid-item">item10</li> </ul> Using ES6 Class writing: class Draggable { constructor(options) { this.parent = options.element; // Parent element this.cloneElementClassName = options.cloneElementClassName; // Clone element class name this.isPointerdown = false; this.diff = { x: 0, y: 0 }; // Difference relative to the last move this.drag = { element: null, index: 0, lastIndex: 0 }; // Drag element this.drop = { element: null, index: 0, lastIndex: 0 }; // Release element this.clone = { element: null, x: 0, y: 0 }; this.lastPointermove = { x: 0, y: 0 }; this.rectList = []; // Used to save the data obtained by the drag item getBoundingClientRect() method this.init(); } init() { this.getRect(); this.bindEventListener(); } // Get element position information getRect() { this.rectList.length = 0; for (const item of this.parent.children) { this.rectList.push(item.getBoundingClientRect()); } } handlePointerdown(e) { // If it is a mouse click, only respond to the left button if (e.pointerType === 'mouse' && e.button !== 0) { return; } if (e.target === this.parent) { return; } this.isPointerdown = true; this.parent.setPointerCapture(e.pointerId); this.lastPointermove.x = e.clientX; this.lastPointermove.y = e.clientY; this.drag.element = e.target; this.drag.element.classList.add('active'); this.clone.element = this.drag.element.cloneNode(true); this.clone.element.className = this.cloneElementClassName; this.clone.element.style.transition = 'none'; const i = [].indexOf.call(this.parent.children, this.drag.element); this.clone.x = this.rectList[i].left; this.clone.y = this.rectList[i].top; this.drag.index = i; this.drag.lastIndex = i; this.clone.element.style.transform = 'translate3d(' + this.clone.x + 'px, ' + this.clone.y + 'px, 0)'; document.body.appendChild(this.clone.element); } handlePointermove(e) { if (this.isPointerdown) { this.diff.x = e.clientX - this.lastPointermove.x; this.diff.y = e.clientY - this.lastPointermove.y; this.lastPointermove.x = e.clientX; this.lastPointermove.y = e.clientY; this.clone.x += this.diff.x; this.clone.y += this.diff.y; this.clone.element.style.transform = 'translate3d(' + this.clone.x + 'px, ' + this.clone.y + 'px, 0)'; for (let i = 0; i < this.rectList.length; i++) { // Collision detection if (e.clientX > this.rectList[i].left && e.clientX < this.rectList[i].right && e.clientY > this.rectList[i].top && e.clientY < this.rectList[i].bottom) { this.drop.element = this.parent.children[i]; this.drop.lastIndex = i; if (this.drag.element !== this.drop.element) { if (this.drag.index < i) { this.parent.insertBefore(this.drag.element, this.drop.element.nextElementSibling); this.drop.index = i - 1; } else { this.parent.insertBefore(this.drag.element, this.drop.element); this.drop.index = i + 1; } this.drag.index = i; const dragRect = this.rectList[this.drag.index]; const lastDragRect = this.rectList[this.drag.lastIndex]; const dropRect = this.rectList[this.drop.index]; const lastDropRect = this.rectList[this.drop.lastIndex]; this.drag.lastIndex = i; this.drag.element.style.transition = 'none'; this.drop.element.style.transition = 'none'; this.drag.element.style.transform = 'translate3d(' + (lastDragRect.left - dragRect.left) + 'px, ' + (lastDragRect.top - dragRect.top) + 'px, 0)'; this.drop.element.style.transform = 'translate3d(' + (lastDropRect.left - dropRect.left) + 'px, ' + (lastDropRect.top - dropRect.top) + 'px, 0)'; this.drag.element.offsetLeft; // trigger redraw this.drag.element.style.transition = 'transform 150ms'; this.drop.element.style.transition = 'transform 150ms'; this.drag.element.style.transform = 'translate3d(0px, 0px, 0px)'; this.drop.element.style.transform = 'translate3d(0px, 0px, 0px)'; } break; } } } } handlePointerup(e) { if (this.isPointerdown) { this.isPointerdown = false; this.drag.element.classList.remove('active'); this.clone.element.remove(); } } handlePointercancel(e) { if (this.isPointerdown) { this.isPointerdown = false; this.drag.element.classList.remove('active'); this.clone.element.remove(); } } bindEventListener() { this.handlePointerdown = this.handlePointerdown.bind(this); this.handlePointermove = this.handlePointermove.bind(this); this.handlePointerup = this.handlePointerup.bind(this); this.handlePointercancel = this.handlePointercancel.bind(this); this.getRect = this.getRect.bind(this); this.parent.addEventListener('pointerdown', this.handlePointerdown); this.parent.addEventListener('pointermove', this.handlePointermove); this.parent.addEventListener('pointerup', this.handlePointerup); this.parent.addEventListener('pointercancel', this.handlePointercancel); window.addEventListener('scroll', this.getRect); window.addEventListener('resize', this.getRect); window.addEventListener('orientationchange', this.getRect); } unbindEventListener() { this.parent.removeEventListener('pointerdown', this.handlePointerdown); this.parent.removeEventListener('pointermove', this.handlePointermove); this.parent.removeEventListener('pointerup', this.handlePointerup); this.parent.removeEventListener('pointercancel', this.handlePointercancel); window.removeEventListener('scroll', this.getRect); window.removeEventListener('resize', this.getRect); window.removeEventListener('orientationchange', this.getRect); } } // Instantiate new Draggable({ element: document.querySelector('.grid'), cloneElementClassName: 'clone-grid-item' }); Demo: jsdemo.codeman.top/html/dragga… 3. Why not use HTML drag and drop API? Because the native 4. SummaryThe basic function of drag-and-drop sorting has been implemented, but there are still many shortcomings. Features like nested dragging, dragging across lists, and automatic scrolling when dragging to the bottom are not implemented. This is the end of this article about the details of implementing drag and drop sorting with js. For more relevant content about implementing drag and drop sorting with js, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: 25 Examples of Using Circular Elements in Web Design
>>: Docker uses Git to implement the detailed process of Jenkins release and test projects
This article introduces and shares the responsive...
Docker Quickly Install Zookeeper I haven't us...
Table of contents Query cache optimization Overvi...
Since PHP7 came out, as a fan of the latest versi...
During the configuration of Jenkins+Tomcat server...
MYSQL commonly used query commands: mysql> sel...
In order to avoid repeatedly entering the Docker ...
1. Introduction to Data Integrity 1. Introduction...
Table of contents 1. Start and stop service instr...
Function currying (black question mark face)? ? ?...
Cerebro is an evolution of the Elasticsearch Kopf...
The use of Vue+ElementUI Tree is for your referen...
Assume that a node in the three-node MGR is abnor...
1: masterha_check_repl replica set error replicat...
react.js framework Redux https://github.com/react...