全局拖拽上傳文件(相似百度網盤)的實現及踩坑

記錄下,開發需求是實現一個相似百度網盤全局拖拽的功能,兼容瀏覽器,IE0以上。實現思路是,採用原聲的拖拽事件。監聽window上的dragenter事件,拖拽目標節點是fixed罩住頁面的dropZone節點。javascript

  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

搜了好久,搜到一個屬性,可完美的解決問題。在文案節點上添加css屬性pointer-events:none;MDN上的解釋以下:html

除了指示該元素不是鼠標事件的目標以外,值none表示鼠標事件「穿透」該元素而且指定該元素「下面」的任何東西。

意思就是,加了這個屬性以後,不會觸發dom事件,就像一個幽靈,鼠標點擊,拖動等等,都是穿透這個元素的。當時看到這個屬性,emmmm以爲有文化的人耍起流氓,真的是..一言難盡吧java

相關文章
相關標籤/搜索