簡體   English   中英

你如何去抖動/扼殺Shadow DOM事件?

[英]How do you debounce/throttle Shadow DOM events?

我在內部將一個事件處理程序附加到我的陰影元素(我沒有將事件傳播給用戶),處理dragover事件。 一切正常,直到我試圖去除事件。 似乎當我使用setTimeout ,事件被更改,以便它就像被觸發一樣(事件目標是) <my-element>

為了使這更清楚; <my-element>有它的陰影dom,其中包含一些元素。 如果沒有setTimeout ,則會按預期在其中一個陰影元素上觸發事件。 例如<my-element>的陰影dom中的<li><button> <my-element> 一旦我嘗試使用setTimeout去抖動事件,事件目標就會更改為<my-element>

所以我的問題是; 可以/你如何去除影子dom事件?

HTML

<html>
    <head></head>
    <body>
       <my-element>
           #shadow-root (open)
               <ul>
                   <li draggable="true">
                        <button>Hi</button>
                   </li>
                   <li draggable="true">
                        <button>Hi</button>
                   </li>
               </ul>
              <ul class="drop-target">
              </ul>
       </my-element>
    </body>
</html>

使用Javascript:

    //...class code
    attachEventHandler(){
        let self = this;

        self.shadowElement.addEventListener('dragover', (function debouncedDragOverFactory(){
            let timeoutId = 0,
                evObj;

            return function debouncedDragOver(ev){
                evObj = ev; //Only tracking the last event
                if(!timeoutId){
                    timeoutId = setTimeout(function(){
                        self.onDragOver(evObj); //self is 'this' pointer of the class this code is in.
                                                //onDragOver handles the drag event, obvisouly. 
                        timeoutId = 0;
                    }, 100);
                }
            };
        })());
    }

[更新]
這是一個Plunker的例子

我在第二個事件處理程序中對setTimeout設置了1秒延遲。 所以你會看到一堆'DIV'節點名稱然后滾動'LIST-EXAMPLE'節點名稱。

div是在shadowRoot中。

LIST-EXAMPLE是用戶在窗口范圍事件中看到的內容。

為了解決事件的變化,在第三個事件處理程序中,我將數據復制到我想要的位置。

所以我想在我的更新中我回答了我自己的問題。

這是一個Plunker的例子

我在第二個事件處理程序中對setTimeout設置了1秒延遲。 所以你會看到一堆'DIV'節點名稱然后滾動'LIST-EXAMPLE'節點名稱。

div是在shadowRoot中。

LIST-EXAMPLE是用戶在窗口范圍事件中看到的內容。

為了解決事件的變化,在第三個事件處理程序中,我將數據復制到我想要的位置。

因此,您可以執行通常要進行去抖動的操作,但請確保復制事件所需的數據,並在工作函數中使用該副本。

要使用可能的解決方案從上面更新我的代碼......

//...class code
attachEventHandler(){
    let self = this;

    self.shadowElement.addEventListener('dragover', (function debouncedDragOverFactory(){
        let timeoutId = 0,
            evTarget;

        return function debouncedDragOver(ev){
            evTarget = ev.target; //Copy the data off that I need
            if(!timeoutId){
                timeoutId = setTimeout(function(){
                    self.onDragOver(evTarget);
                    timeoutId = 0;
                }, 100);
            }
        };
    })());
}

您還可以將所需的數據作為setTimeout函數的第三個參數傳遞:

li.addEventListener('dragover', function(e){
    setTimeout(function(nodeName){
        output.textContent = '3' + nodeName + '\n' + output.textContent;    
    }, 2000, e.target.nodeName);
});

暫無
暫無

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

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