记录下,开发需求是实现一个类似百度网盘全局拖拽的功能,兼容浏览器,IE0以上。实现思路是,采用原声的拖拽事件。监听window上的dragenter事件,拖拽目标节点是fixed罩住页面的dropZone节点。
- 监听window上的dragenter事件,显示拖拽的蒙层
- 监听目标节点dropzone上的拖拽(dragover, dragenter, dragleave, drop)事件。由于dragZone是fixed 到整个页面的,所以在页面全局拖拽时,都会显示蒙层。
- drop时,拖拽结束,拿到拖拽的文件
<html>
<body>
<style type="text/css">
div#dropZone {
background: gray;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
opacity: 0.6;
visibility: hidden;
}
.desc{
position: absolute;
left: 50%;
top:50%;
}
</style>
<div id="dropZone">
<p class="desc">可全局拖拽blablabla的文案</p>
</div>
<script type="text/javascript">
//拖拽的目标节点
var dropZone = document.getElementById('dropZone');
function showDropZone() {
dropZone.style.visibility = "visible";
}
function hideDropZone() {
dropZone.style.visibility = "hidden";
}
function allowDrag(e) {
if (true) {
// Test that the item being dragged is a valid one
e.dataTransfer.dropEffect = 'copy';
e.preventDefault();
}
}
function handleDrop(e) {
e.preventDefault();
hideDropZone();
alert('Drop!');
}
// 监听widow上的事件
window.addEventListener('dragenter', function(e) {
showDropZone();
});
dropZone.addEventListener('dragenter', allowDrag);
dropZone.addEventListener('dragover', allowDrag);
dropZone.addEventListener('dragleave', function(e) {
hideDropZone();
});
dropZone.addEventListener('drop', handleDrop);
</script>
</body>
demo跑起来会发现,当拖拽到dragZone的子节点,显示的文字上时,拖拽会失效。按理说,事件应该冒泡到父节点并且能正常拖动才对,但是 现实总是这么骨感
搜了很久,搜到一个属性,可完美的解决问题。在文案节点上添加css属性pointer-events:none;MDN上的解释如下:
除了指示该元素不是鼠标事件的目标之外,值none表示鼠标事件“穿透”该元素并且指定该元素“下面”的任何东西。
意思就是,加了这个属性之后,不会触发dom事件,就像一个幽灵,鼠标点击,拖动等等,都是穿透这个元素的。当时看到这个属性,emmmm觉得有文化的人耍起流氓,真的是..一言难尽吧
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。