基于grid布局实现页面元素的动态拖拽替换

您所在的位置:网站首页 甘特图vue控件 基于grid布局实现页面元素的动态拖拽替换

基于grid布局实现页面元素的动态拖拽替换

2023-03-13 19:42| 来源: 网络整理| 查看: 265

基于grid布局实现页面元素的动态拖拽替换

本人看见网上的都是基于flex布局的动态拖拽,就想尝试写一下grid布局的拖拽实现一下,于是有了本篇文章,本篇主要都是基原生js实现,文章主要时提供了一个思路,需要时请根据自己的实际需求更改或者封装。觉得不错记得点个赞! 在这里插入图片描述

DOCTYPE html> Document #grid-container { width: 150px; height: 150px; display: grid; /* grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); */ } .draggable-element { /* some styles for element */ user-select: none; width: 50px; height: 50px; display: inline-block; text-align: center; outline: 1px solid #333; } let elements = ''; let offset = { x: 0, y: 0 }; let isDragging = false; let column = 3 let columnWidth = 50 let dataArray = [ { label: '1', value: '1' }, { label: '2', value: '2' }, { label: '3', value: '3' }, { label: '4', value: '4' }, { label: '5', value: '5' }, { label: '6', value: '6' }, { label: '7', value: '7' }, { label: '8', value: '8' }, { label: '9', value: '9' } ]; let dataCloneArray = deepClone(dataArray); let type = 'resort' // 拖拽类型:重排resort/替换replace function init() { let parentElement = document.getElementById('grid-container') parentElement.style.gridTemplateAreas = joinGridArea(); parentElement.innerHTML = ''; dataCloneArray.forEach( (item, index) => { let element = document.createElement('div'); element.id = `element-${item.label}`; element.classList.add("draggable-element"); element.innerText = item.value; element.style.color = 'red'; element.style.gridArea = `area-${index}`; parentElement.appendChild(element); }); elements = document.getElementsByClassName("draggable-element") for (let i = 0; i const len = dataCloneArray.length let areaStr = '' for (let i = 0; i areaStr += '"area-' + i + ' ' if (column === 1) { areaStr += '"' } } else if (i % column === column - 1) { areaStr += 'area-' + i + '"' } else { areaStr += 'area-' + i + ' ' } } if (len % column !== 0) { const emptyLength = column - (len % column) areaStr += new Array(emptyLength).fill('.').join(' ') + '"' } return areaStr } function startDrag(event) { let element = event.target; element.style.boxShadow = '#e6e6e6 0 0 10px 10px'; element.style.zIndex = 100; element.style.position = 'relative'; element.style.left = '0px'; element.style.top = '0px'; isDragging = true; offset.x = event.clientX ; offset.y = event.clientY; } function doDrag(event) { if (isDragging) { let x = event.clientX - offset.x let y = event.clientY - offset.y let element = event.target; const { minX, maxX, minY, maxY } = getRangeOfEl(element) // console.log(maxX, maxY, minX, minY); x = x maxX ? maxX : x) y = y maxY ? maxY : y) // console.log(x, y); requestAnimationFrame(() => { element.style.left = x + "px"; element.style.top = y + "px"; }); } } function stopDrag(event) { isDragging = false; let element = event.target; element.style.boxShadow = 'none'; changeBlock(element) } // 计算当前元素可移动的区域 function getRangeOfEl(moveEl) { const index = parseInt(moveEl.style.gridArea.split(' / ')[0].split('-')[1]) const res = {} const currentColummn = index % column const allRow = Math.ceil(dataCloneArray.length / column) const currentRow = Math.floor(index / column) res.minX = -((moveEl.offsetWidth) * currentColummn) res.maxX = (column - currentColummn - 1) * (moveEl.offsetWidth + 5) res.minY = -((moveEl.offsetHeight + 5) * currentRow) res.maxY = (allRow - currentRow - 1) * (moveEl.offsetHeight + 5) return res } // 拖拽结束时重排数据或者替换数据 function changeBlock(moveEl) { // 将方块移入到对应的区域中 const { nowIndex, index } = getIndexOfMoveEL(moveEl) console.log(nowIndex, index); if (type === 'replace') { const temp = dataCloneArray[index] dataCloneArray[index] = dataCloneArray[nowIndex] dataCloneArray[nowIndex] = temp } else { let element = dataCloneArray.splice(index, 1)[0] dataCloneArray.splice(nowIndex, 0, element) } moveEl.style.left = 0 moveEl.style.top = 0 dataArray = dataCloneArray init() } // 拖拽时根据位置计算位置 // 返回当前的位置和之前的位置 function getIndexOfMoveEL(moveEl) { const x = parseInt(moveEl.style.left.split('px')[0]) const y = parseInt(moveEl.style.top.split('px')[0]) const index = parseInt(moveEl.style.gridArea.split(' / ')[0].split('-')[1]) console.log(x, y, index); let nowIndex = 0 if (x nowIndex = index + (Math.round(Math.abs(x) / moveEl.offsetWidth)) } if (y nowIndex = nowIndex + (Math.round(Math.abs(y) / moveEl.offsetHeight)) * column } return { nowIndex, index } } // 深度克隆函数 function deepClone(obj) { if (obj === null || typeof obj !== "object") return obj; if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); if (obj instanceof Set) return new Set(obj); if (obj instanceof Map) return new Map(obj); if (obj instanceof Array) { let clone = []; for (let i = 0; i }; for (let key in obj) { if (obj.hasOwnProperty(key)) { clone[key] = deepClone(obj[key]); } } return clone; }

上述代码在按下左键拖拽元素时,获取鼠标位置 ,并对元素的位置进行计算重排。具体请参见上面的注释。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3