2017-12-14 3 views
2

부모 요소 나 다른 ID, 클래스 루프 및 기타 요소를 명시 적으로 검색하지 않고도 JavaScript에서 드래그 앤 드롭이 제대로 작동하도록하려고합니다. 해키 마술.캡쳐 단계가 사용되는 경우에도 OnDrop 이벤트 대상은 자식 위로 놓을 때 자식입니다.

지금 요소 풀의 요소 중 하나를 드래그하여 회색 영역으로 끌면 요소가 놓기 영역에 복사됩니다 (지금까지 모든 것이 정확함). 기본적으로 끌어온 요소의 HTML을 복사하고, 놓기 영역 (대상)을 지우고 새 요소를 추가합니다.

문제는 이미 일부 하위 요소가 놓기 영역에 있고 하위 요소 위로 끌어 놓으면 시작됩니다. 그런 다음 drop 이벤트의 대상은 자식 요소이며 이벤트가 첨부 된 div는 아닙니다. 이로 인해 드래그 된 요소가 지워지고 드롭 컨테이너 대신 자식으로 복사됩니다.

자식 또는 주 드롭 컨테이너에 직접 놓아도 상관없이 대상은 이벤트 캡처 모드를 사용할 때 항상 부모 노드 여야합니다.

다음은 JS Fiddle의 예제 코드입니다. 캡처를 사용하여 이벤트 리스너를 사용하고 있지만 어쨌든 버블 링 단계를 수행하고 캡처 중 하나를 무시하는 것으로 보입니다. 왜?

이 작업을 수행하는 적절한 방법은 무엇입니까?

function onDrag(ev) { 
 
    var el = ev.target; 
 
    //console.log("Drag: " + ev.target.outerHTML) 
 
    ev.dataTransfer.setData('text/html', ev.target.outerHTML); 
 
} 
 

 
function onContainerOver(ev) { 
 
    ev.preventDefault(); 
 
    ev.dataTransfer.dropEffect = "move" 
 
} 
 

 
function onContainerDrop(ev) { 
 
    ev.preventDefault(); 
 
    //console.log("Drop: " + ev.dataTransfer.getData("text/html")) 
 
    ev.target.innerHTML = ev.dataTransfer.getData("text/html"); 
 
} 
 

 
document.getElementById('target').addEventListener('drop', onContainerDrop, true); // This should not bubble, but it does. Target is always the child first rather than the element where the event listener resides. Why???
#list {} 
 

 
.el { 
 
    padding: 5px; 
 
    margin: 10px; 
 
    border: solid 1px black; 
 
    background-color: #86d4ff; 
 
    cursor: move; 
 
    line-height: 1em; 
 
    text-align: left; 
 
} 
 

 
#target { 
 
    min-height: 200px; 
 
    width: 100%; 
 
    background-color: #ffdea6; 
 
    border: 1px dashed gray; 
 
    text-align: center; 
 
    line-height: 100px; 
 
}
<div id="list"> 
 
    <div class="el" draggable="true" ondragstart="onDrag(event)">ELEMENT A</div> 
 
    <div class="el" draggable="true" ondragstart="onDrag(event)">ELEMENT B</div> 
 
    <div class="el" draggable="true" ondragstart="onDrag(event)">ELEMENT C</div> 
 
</div> 
 
<div id="target" ondragover="onContainerOver(event)"> 
 
    Drop Here 
 
</div>
오리지널 JSFiddle Link.

답변

1

내가 찾고 있었던 정확하게 수행되는 이벤트에서 "currentTarget"요소의 가용성을 통보하지 않았다, 신경 쓰지 마 에 대한.

그래서 대신 "event.target이"는 이벤트가 트리거 실제 부모 요소를 얻기 위해 "event.currentTarget"해야 사용. 가 이

업데이트 JS

https://jsfiddle.net/xs20xy27/ : 당신은 자식 요소에 아무것도 떨어 뜨리거나 어떤 이벤트가 자식 요소에 발생하는 경우

function onDrag(ev){ 
    var el = ev.srcElement; 
    console.log("Drag: " + ev.srcElement.outerHTML) 
    ev.dataTransfer.setData('text/html', ev.srcElement.outerHTML); 
} 

function onContainerOver(ev){ 
    ev.preventDefault(); 
    ev.dataTransfer.dropEffect = "move" 
} 

function onContainerDrop(ev){ 
    ev.preventDefault(); 
    console.log("Drop: " + ev.dataTransfer.getData("text/html")) 
    ev.currentTarget.innerHTML = ev.dataTransfer.getData("text/html"); 
} 

document.getElementById('target').addEventListener('drop', onContainerDrop, true); // This should not bubble, but it does. Target is always the child first rather than the element where the event listener resides. Why??? 
2

에서, 이벤트 대상가 여기에

는 작업 JSFiddle입니다 그것이 항상 이벤트가 발생한 곳이기 때문에 항상 자식 요소입니다. 그것은 목표입니다.그런 다음이 이벤트가

┌─────────────────────────────────────┐ 
│ ┌───────────────────────────────┐ │ 
│ │ Child [Target][CurrentTarget] │ │ 
│ └───────────────────────────────┘ │ 
│   Parent Element    │ 
└─────────────────────────────────────┘ 

그런 다음이 이벤트로 부모 요소의 이벤트 핸들러에 전달되는 두 대상CurrentTarget으로 자식 요소로 자식 요소의 이벤트 핸들러에 전달되는

┌─────────────────────────────────────┐ 
│ ┌────────────────────────┐  │ 
│ │  Child [Target]  │  │ 
│ └────────────────────────┘  │ 
│    Parent     │ 
└─────────────────────────────────────┘ 

하위 요소는 이고 대상은이고 부모 요소는 현재 대상

최상위 요소에 도달 할 때 또는 이벤트 핸들러 event.stopPropagation()

를 호출
버블 링이 이벤트가 취소 될 때까지 그런 다음 이벤트는 동일한 방식으로 연속하여 DOM 트리에서 상위 요소로 전달된다
┌─────────────────────────────────────┐ 
│ ┌───────────────────────────────┐ │ 
│ │  Child [Target]   │ │ 
│ └───────────────────────────────┘ │ 
│   Parent [CurrentTarget]  │ 
└─────────────────────────────────────┘ 

그래서 세 번째 매개 변수 useCapturetrue로 설정하여 이벤트 핸들러를 만들면 어떤 일이 발생합니까?입니다. [: 부모currentTarget] 다음 자식 요소 [currentTarget은 : 자식]뿐만 아니라 항상 이벤트 대상는이 경우

parentElement.addEventListener('click', myClickHandler, true); 

는, 이벤트는 먼저 부모 요소에 전달 항상 하위 요소이 이벤트가 트리거 된 위치이기 때문입니다. 이벤트가 DOM을 통과 할

소개 CurrentTargetthis MDN WebDocs page 말한다

,

는 이벤트에 대한 현재 대상을 식별합니다. 이벤트가 발생한 요소를 식별하는 event.target과 반대로 이벤트 처리기 이 연결된 요소를 항상 참조합니다.

관련 문제