let dragging;fileList.addEventListener('dragstart', (event) => { dragging = event.target;});fileList.addEventListener('dragover', (event) => { event.preventDefault(); const target = event.target; if (target !== dragging && target.nodeName === 'LI') { const rect = target.getBoundingClientRect(); const next = (event.clientY - rect.top) > (rect.bottom - event.clientY); fileList.insertBefore(dragging, next ? target.nextElementSibling : target); }});fileList.addEventListener('dragend', (event) => { dragging = null;});解释这段代码
时间: 2024-03-28 21:37:51 浏览: 130
这段代码是一个文件列表的拖拽排序功能。具体解释如下:
第一行定义了一个变量 `dragging`,用来记录当前被拖拽的元素。
第二行给文件列表添加了一个 `dragstart` 事件监听器,当拖拽开始时,将当前被拖拽的元素记录到 `dragging` 变量中。
第三行给文件列表添加了一个 `dragover` 事件监听器,当拖拽元素在列表中移动时,阻止默认行为,即不允许拖拽元素在列表中生成新的拖拽元素。
第四行定义了一个变量 `target`,记录当前被拖拽元素所在的目标元素。
第五行判断当前目标元素是否与被拖拽元素相同,并且目标元素的 nodeName 是 'LI',即目标元素是一个列表项。
第六行获取目标元素的位置信息,即获取目标元素的位置和大小。
第七行判断当前被拖拽元素相对于目标元素的位置,如果拖拽元素的位置在目标元素的下半部分,那么将拖拽元素插入到目标元素的后面,否则插入到目标元素的前面。
第八行给文件列表添加了一个 `dragend` 事件监听器,当拖拽结束时,将 `dragging` 变量设置为 null,即清空被拖拽元素的记录。
相关问题
// draggable.js import { onMounted, onBeforeUnmount } from 'vue' export default { mounted(el) { el.setAttribute('draggable', true) let startX, startY, initialLeft, initialTop, currentX, currentY const onDragStart = (e) => { e.stopPropagation() startX = e.clientX || e.touches[0].clientX startY = e.clientY || e.touches[0].clientY initialLeft = el.offsetLeft initialTop = el.offsetTop el.classList.add('dragging') } const onDrag = (e) => { e.stopPropagation() currentX = (e.clientX || e.touches[0].clientX) - startX currentY = (e.clientY || e.touches[0].clientY) - startY el.style.left = `${initialLeft + currentX}px` el.style.top = `${initialTop + currentY}px` } const onDragEnd = (e) => { e.stopPropagation() el.classList.remove('dragging') } el.addEventListener('dragstart', onDragStart) el.addEventListener('drag', onDrag) el.addEventListener('dragend', onDragEnd) el.addEventListener('touchstart', onDragStart) el.addEventListener('touchmove', onDrag) el.addEventListener('touchend', onDragEnd) onMounted(() => { el.classList.add('draggable') }) onBeforeUnmount(() => { el.removeEventListener('dragstart', onDragStart) el.removeEventListener('drag', onDrag) el.removeEventListener('dragend', onDragEnd) el.removeEventListener('touchstart', onDragStart) el.removeEventListener('touchmove', onDrag) el.removeEventListener('touchend', onDragEnd) el.classList.remove('draggable') el.classList.remove('dragging') }) } } 解决这个报错 TypeError: Cannot read properties of undefined (reading '0')
在这段代码中,并没有显示的报错信息,所以很难确定你遇到的报错是哪个。但是,根据你提供的代码以及报错信息,我们可以猜测,可能是在这行代码中出现了问题:
```
startX = e.clientX || e.touches[0].clientX
```
由于此行代码使用了逻辑或运算符,如果 `e.clientX` 为 undefined,则会尝试读取 `e.touches[0].clientX`,但是 `e.touches` 可能为空,这就会导致报错 `Cannot read properties of undefined (reading '0')`,因为你无法从一个未定义的对象中读取属性。
为了解决这个问题,你可以在使用逻辑或运算符之前,先检查 `e` 对象中的属性是否存在。例如,你可以这样修改代码:
```
startX = e.clientX || (e.touches && e.touches[0] && e.touches[0].clientX)
startY = e.clientY || (e.touches && e.touches[0] && e.touches[0].clientY)
```
这样,如果 `e.clientX` 为 undefined,就会尝试读取 `e.touches[0].clientX`,但是在读取之前,会先检查 `e.touches` 是否存在,并且检查 `e.touches[0]` 是否存在,以避免出现上述报错。
// draggable.js import { onMounted, onBeforeUnmount } from 'vue' export default { mounted(el) { console.log('el',el) el.setAttribute('draggable', true) let startX, startY, initialLeft, initialTop, currentX, currentY const onDragStart = (e) => { console.log('e',e.preventDefault()) e.stopPropagation() // e.preventDefault() startX = e.clientX || e.touches[0].clientX startY = e.clientY || e.touches[0].clientY initialLeft = el.offsetLeft initialTop = el.offsetTop el.classList.add('dragging') } const onDrag = (e) => { e.stopPropagation() currentX = (e.clientX || e.touches[0].clientX) - startX currentY = (e.clientY || e.touches[0].clientY) - startY el.style.left = `${initialLeft + currentX}px` el.style.top = `${initialTop + currentY}px` } const onDragEnd = (e) => { e.stopPropagation() el.classList.remove('dragging') } el.addEventListener('dragstart', onDragStart) el.addEventListener('drag', onDrag) el.addEventListener('dragend', onDragEnd) el.addEventListener('touchstart', onDragStart) el.addEventListener('touchmove', onDrag) el.addEventListener('touchend', onDragEnd) onMounted(() => { el.classList.add('draggable') }) onBeforeUnmount(() => { el.removeEventListener('dragstart', onDragStart) el.removeEventListener('drag', onDrag) el.removeEventListener('dragend', onDragEnd) el.removeEventListener('touchstart', onDragStart) el.removeEventListener('touchmove', onDrag) el.removeEventListener('touchend', onDragEnd) el.classList.remove('draggable') el.classList.remove('dragging') }) } } 为什么拖拽时会出现虚影,残影, 怎么解决这个问题
出现拖拽时的虚影、残影问题,是因为浏览器默认会在拖拽时添加一个半透明的影像,以便用户可以清楚地看到拖拽的对象和目标位置。这个影像在拖拽结束后会自动消失。
您可以尝试在dragstart事件中调用setData方法来阻止浏览器默认的影像行为,例如:
```
const onDragStart = (e) => {
e.stopPropagation();
e.dataTransfer.setData('text/plain', ''); // 阻止浏览器默认影像
startX = e.clientX || e.touches[0].clientX;
startY = e.clientY || e.touches[0].clientY;
initialLeft = el.offsetLeft;
initialTop = el.offsetTop;
el.classList.add('dragging');
};
```
此外,您还可以在CSS中使用`-webkit-user-drag: none;`来阻止元素的默认拖拽效果,例如:
```
.draggable {
-webkit-user-drag: none;
user-select: none;
}
```
请注意,这种方法可能会影响到元素的交互性,因此需要谨慎使用。
阅读全文
相关推荐
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![pptx](https://img-home.csdnimg.cn/images/20241231044947.png)