//为了方便借助vue和jquery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>拖拽排序</title> <style> ul, li { list-style: none; padding: 0; margin: 0; } ul { margin: 0 auto; width: 200px; } .item { font-size: 15px; border: 1px solid #eee; border-radius: 4px; padding: 8px 10px; margin: 15px 0; } .item.before { margin-top: 45px; transition: margin-top 0.15s ease-in; } .item.after { margin-bottom: 45px; transition: margin-bottom 0.15s ease-in; } </style> </head> <body> <div id="app"> <ul class="items"> <li class="item" v-for="i in 5" draggable="true" @dragstart="dragstart($event)">{{i}}</li> </ul> </div> <script src="./libs/jquery.min.js"></script> <script src="./libs/vue.js"></script> <script> new Vue({ el: '#app', data: { }, methods: { dragstart(e) { let dragTarget = $(e.currentTarget); let overTarget = null; let allItems = dragTarget.parent().children('.item'); let x = null, y = null; let overTargetSize = { width: null, height: null, } for (let i = 0; i < allItems.length; i++) { const el = allItems[i]; el.ondragenter = function (evt) { overTarget = $(evt.target) return true; } el.ondragover = function (evt) { x = evt.offsetX; y = evt.offsetY; // overTargetSize.width = evt.target.offsetWidth; // overTargetSize.height = evt.target.offsetHeight; $(allItems).removeClass('after').removeClass('before') if (y > 19) { $(evt.target).addClass('after'); } else if (y <= 19) { $(evt.target).addClass('before'); } } el.ondragend = function (evt) { if (y > 19) { $(overTarget).after(dragTarget) } else if (y <= 19) { $(overTarget).before(dragTarget) } $(allItems).removeClass('after').removeClass('before'); x = null, y = null; return false; } } }, } }) </script> </body> </html>