我有一个包含多个子集的列表,我希望将每个子集的dragEvents保持为单独的,但是我希望将列表保留为一个列表:
<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中删除它们,但是它不起作用。这两个函数的作用域如下:
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中。
谢谢你的帮助
发布于 2022-02-17 10:11:58
在添加新侦听器之前,在dragStart函数中更容易使用removeEventListener (尤其是因为并非所有的拖放都以成功的下降结束)。
而不是将事件侦听器附加为元素的方法:
li.addEventListener(...)
如果将事件侦听器作为对象属性附加到元素(假设不需要同一元素上相同类型的多个事件侦听器),则更容易跟踪事件侦听器。这还确保每个元素只有一个活动事件侦听器(如果这是您想要的话)。
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 )
}
}.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;
}<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>
https://stackoverflow.com/questions/71150581
复制相似问题