class Draggable {
el: HTMLElement | null
children: HTMLElement[] | null
draggingElement: HTMLElement | null
constructor(className: string) {
this.el = document.querySelector(className)
if (!this.el) {
console.warn(`cant'find the element of ${className}`)
}
this.children = this.el && Array.prototype.slice.call(this.el?.children)
this.children?.forEach(v => {
v.draggable = true
})
this.bindEvents()
this.draggingElement = null
}
bindEvents() {
this.el?.addEventListener('dragover', (e) => e.preventDefault())
document.addEventListener('dragover', (e) => e.preventDefault())
this.children?.forEach(v => {
v.addEventListener('dragstart', (e) => this.handlerDragstart(e, v))
v.addEventListener('dragover', (e) => this.dragover(e))
v.addEventListener('dragenter', (e) => this.dragenter(e))
v.addEventListener('dragend', (e) => this.dragend(e, v))
})
}
handlerDragstart(e: DragEvent, element: HTMLElement) {
this.draggingElement = element
setTimeout(() => {
element.classList.add('dragging')
}, 10);
}
dragover(e: DragEvent) {
e.preventDefault()
const current_pos = e.clientY
const otherElement = this.children?.filter(v => v != this.draggingElement)
const referenceHeights = []
otherElement?.forEach(item => {
referenceHeights.push({ height: item.offsetTop + item.offsetHeight / 2, e: item })
})
referenceHeights.push({ height: current_pos, e: this.draggingElement, dragging: true })
// 排序
referenceHeights.sort((a, b) => a.height - b.height)
const res = referenceHeights.map(v => v.e) as Node[]
this.el?.replaceChildren(...res)
}
dragenter(e: DragEvent) {
e.preventDefault()
}
dragend(e: DragEvent, element: HTMLElement) {
e.preventDefault()
element.classList.remove('dragging')
}
}
const drag = new Draggable('.container')
js拖拽排序
最新推荐文章于 2025-06-09 15:33:07 发布