簡體   English   中英

事件傳播、覆蓋和拖放事件

[英]Event propagation, overlay and drag-and-drop events

當用戶將文件拖到窗口上時,我想在視口上覆蓋一個 div。

但是,我在事件傳播方面遇到了麻煩。 當我將疊加層設置為display: block時,它似乎會觸發一個dragleave事件,然后是另一個dragenter ,然后是另一個dragleave ,因此它始終處於 post-dragleave 狀態。 當然,我在事件對象上調用e.stopPropagation()e.preventDefault() ,但這似乎沒有什么區別。

當您在窗口上拖動某些東西時, console.log()輸出:

拖拉機
拖拉機
拖離
拖拉機
拖離

的CSS。 #overlay設置為display: none默認情況下,但會顯示body是否有dragenter類:

    body {
        position: absolute;
        height: auto;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: 0;
        padding: 0;
    }

    #overlay {
        position: absolute;        
        height: auto;
        width: auto;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: url(bg.png) repeat-x top right, url(bg.png) repeat-x bottom left, url(bg.png) repeat-y top right, url(bg.p
ng) repeat-y bottom left;
        display: none;
    }

    body.dragenter #overlay {
        display: block;
    }

JavaScript; 在 dragenter 上添加 ' dragenter ' 類並在dragleave上刪除它:

$(document).on('dragenter', function (e) {
    e.stopPropagation();
    e.preventDefault();
    console.log('dragenter');
    $(document.body).addClass('dragenter');
});

$(document).on('dragleave', function (e) {
    e.stopPropagation();
    e.preventDefault();
    console.log('dragleave';
    $(document.body).removeClass('dragenter');
});

的HTML:

<body>
<div id="overlay">...</div>
...    
</body>

您的疊加層占據了整個文檔的大小,當您拖入時,它會填滿其空間,並且您的鼠標實際上已從正文中取出,現在位於疊加層上方。 這會觸發 mouseleave/mouseenter 循環。 為了實現您的目標,您可能希望將事件綁定到具有高 z-index 的透明覆蓋層,而不是具有較低 z-index 的可見覆蓋層。 這將使事件保持在最高元素中。

例子:

http://jsfiddle.net/scottux/z7yaB/

感謝 Scottux,這讓我走上了正確的道路。

唯一的問題是它也覆蓋了頁面的其余部分,因此沒有任何元素或輸入是可點擊的。 默認情況下,我必須使用“ display: none ”隱藏#dragOverlay 並在此事件中顯示它

// Display an overlay when dragging a file over
$('*:visible').live('dragenter', function(e) {
    e.stopPropagation();
    $('body').addClass('drag-enter');
});
    var dropZone = function() {
        var self = this;
        this.eTimestamp = 0;
        this.showDropZone = function(e) {
            e.stopPropagation();
            e.preventDefault();
            if (self.eTimestamp + 300 < e.timeStamp) {
                $("#coverDropZone").show();
                self.eTimestamp = e.timeStamp;
            }
            return false;
        }
        this.hideDropZone = function(e) {
            e.stopPropagation();
            e.preventDefault();
            if (self.eTimestamp + 300 < e.timeStamp) {
                $("#coverDropZone").hide();
                self.eTimestamp = e.timeStamp;
            }
            return false;
        }
        this.showImage = function(e) {
            e.stopPropagation();
            e.preventDefault();
            console.log(e);
            return false;
        }
        document.addEventListener('dragenter', self.showDropZone, false);
        document.addEventListener('dragleave', self.hideDropZone, false);
        document.addEventListener('drop', self.showImage, false);
    }

簡單的解決方案是使用dragover而不是使用dragenter

dragover 發生拖動時,當鼠標移到元素上時會觸發此事件。 很多時候,在監聽器期間發生的操作將與 dragenter 事件相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM