全局拖拽上传文件(类似百度网盘)的实现及踩坑

HudsonLeo 发布于6月前 阅读240次
0 条评论

记录下,开发需求是实现一个类似百度网盘全局拖拽的功能,兼容浏览器,IE0以上。实现思路是,采用原声的拖拽事件。监听window上的dragenter事件,拖拽目标节点是fixed罩住页面的dropZone节点。

  1. 监听window上的dragenter事件,显示拖拽的蒙层
  2. 监听目标节点dropzone上的拖拽(dragover, dragenter, dragleave, drop)事件。由于dragZone是fixed 到整个页面的,所以在页面全局拖拽时,都会显示蒙层。
  3. 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觉得有文化的人耍起流氓,真的是..一言难尽吧

查看原文: 全局拖拽上传文件(类似百度网盘)的实现及踩坑

  • orangerabbit
需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。