首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >removeEventListener不适用于将dragEvents限制为特定类

removeEventListener不适用于将dragEvents限制为特定类
EN

Stack Overflow用户
提问于 2022-02-16 23:28:15
回答 1查看 40关注 0票数 0

我有一个包含多个子集的列表,我希望将每个子集的dragEvents保持为单独的,但是我希望将列表保留为一个列表:

代码语言:javascript
复制
<ul class="draggable-list">
   <li draggable="true" class="draggable set-1" >ONE</li>      
   <li draggable="true" class="draggable set-1" >TWO</li>
   <li draggable="true" class="draggable set-1" >THREE</li>
   <li draggable="true" class="draggable set-2" >one</li>
   <li draggable="true" class="draggable set-2" >two</li>
   <li draggable="true" class="draggable set-2" >three</li>
</ul>

我只在dragstart开始后才将dragover eventListeners添加到某些元素中,然后尝试在dropevent中删除它们,但是它不起作用。这两个函数的作用域如下:

代码语言:javascript
复制
function addListenersToDraggable( li, ruleRep ){
   li.addEventListener( 'dragstart', dragStart )
   li.addEventListener( 'dragenter', dragEvt   )
   li.addEventListener( 'dragleave', dragEvt   )
   li.addEventListener( 'drop', dragEvt )

   function dragStart() {
      ...
      set.forEach( ruleLI => ruleLI.addEventListener( 'dragover' , dragOver ))
   }

   function dragOver(e){
      e.preventDefault();
   }

   function dragEvt(e){
      ...
      // if e.type == "drop"...
      set.forEach( ruleLI => ruleLI.removeEventListener( 'dragover' , dragOver ))
   }
}

我检查了集合是否正确地抓取了元素,并且这两个集合都匹配。我可以拖放,但我不能删除侦听器。我添加dragover的唯一位置是在dragstart中。

谢谢你的帮助

EN

回答 1

Stack Overflow用户

发布于 2022-02-17 10:11:58

在添加新侦听器之前,在dragStart函数中更容易使用removeEventListener (尤其是因为并非所有的拖放都以成功的下降结束)。

而不是将事件侦听器附加为元素的方法:

li.addEventListener(...)

如果将事件侦听器作为对象属性附加到元素(假设不需要同一元素上相同类型的多个事件侦听器),则更容易跟踪事件侦听器。这还确保每个元素只有一个活动事件侦听器(如果这是您想要的话)。

代码语言:javascript
复制
const draggables = Array.from( document.querySelectorAll( ".draggable" ))
draggables.forEach( li => {
  li.addEventListener( 'dragstart', dragStart );
//***instead of eventListener methods on all elements:***
  // li.addEventListener( 'drop'     , dragEvt   );
  // li.addEventListener( 'dragenter', dragEvt   );
  // li.addEventListener( 'dragleave', dragEvt   );
 })

  function dragStart() {
    const dragEl   = this
    const parent   = dragEl.parentElement
    const siblings = Array.from( parent.children )
    dragStartIndex = siblings.indexOf( dragEl )
    const setName  = Array.from( dragEl.classList )
                          .find( className => className.startsWith( "set-" ))
    const set      = Array.from( parent.querySelectorAll( "." + setName ))

//*** removing the attached listeners is easy: ***
    siblings.forEach( li => {
      li.ondragover  = null 
      li.ondragenter = null
      li.ondragleave = null
      li.ondrop      = null
    })
//*** attach listeners only to elements in same class: ***
    set.forEach( li => {
      li.ondragover  = (e) => dragOver( e )
      li.ondragenter = (e) => dragEvt ( e )
      li.ondragleave = (e) => dragEvt ( e )
      li.ondrop      = (e) => dragEvt ( e )
    })
  }

  function dragOver( e ) {
    e.preventDefault();
  }

  function dragEvt( e ) {
    const parentList      = e.target.closest( '.draggable-list' )
    const thisLI          = e.target.closest( '.draggable-list>li' )
    const eventType       = e.type
    const dragEndIndex    = Array.from( parentList.children ).indexOf( thisLI )
    const dragEnterIndex  = Array.from( parentList.children ).indexOf( thisLI )
    if ( dragEnterIndex != -1 ){
      if ( dragEnterIndex > dragStartIndex ){
        if ( eventType == "dragenter"){
          thisLI.classList.add( 'darken-bottom' );
        } else { // if eventType is leave or drop:
          thisLI.classList.remove( 'darken-bottom' );
        }
      } else if ( dragEnterIndex < dragStartIndex ){
        if ( eventType == "dragenter"){
          thisLI.classList.add( 'darken-top' );
        } else { // if eventType is leave or drop:
          thisLI.classList.remove( 'darken-top' );
        }
      } else if ( dragEnterIndex == dragStartIndex ){
        if ( eventType == "dragenter"){
          thisLI.classList.add( 'darken' )
        } else { // if eventType is leave or drop:
          thisLI.classList.remove( 'darken' )
        }
      }
      if ( eventType == "drop" ){
        moveDraggable( dragStartIndex, dragEndIndex, parentList )
      }
    }
  }
      
  function moveDraggable( fromIndex, toIndex, ul ) {
    const liToMove = ul.removeChild( ul.children[ fromIndex ] )
    ul.insertBefore( liToMove, ul.children[ toIndex ])
    if ( fromIndex != toIndex ){
      ul.children[ toIndex ].classList.add( "darken-plonk" )
      setTimeout( () => {
        ul.children[ toIndex ].classList.remove( "darken-plonk" )
      }, 300 )
    }
  }
代码语言:javascript
复制
.set-1 {
  background-color: lightcoral;
}
.set-2 {
  background-color: lightgreen;
}
.set-1, .set-2 {
  border: 1px solid gray;
  padding: 0.5rem;  
  list-style: none;
  width: 10rem;
}

.darken-bottom {
  border-bottom: 3px solid #be2edd;
}
.darken-top {
  border-top: 3px solid #be2edd;
}
.darken, .darken-bottom, .darken-top {
filter: brightness(90%);
transition: all 0.6s ease-out;
}
.darken-plonk {
  filter: brightness(80%);
  border: 2px solid black;
  transition: all 1.5s ease-out;
}
代码语言:javascript
复制
<ul class="draggable-list">
   <li id="li1-1" draggable="true" class="draggable set-1" >ONE</li>      
   <li id="li2-1" draggable="true" class="draggable set-1" >TWO</li>
   <li id="li3-1" draggable="true" class="draggable set-1" >THREE</li>
   <li id="li4-2" draggable="true" class="draggable set-2" >one</li>
   <li id="li5-2" draggable="true" class="draggable set-2" >two</li>
   <li id="li6-2" draggable="true" class="draggable set-2" >three</li>
</ul>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71150581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档