[Web] Drop Event 발생시키기
* 이 글에서 나오는 프로그램은 웹사이트를 돌아다니며 미술관에서 작품을 안내하는 도슨트처럼 각 사이트의 내용을 설명해주는 기능을 한다. 사용자는 프로그램에 내장된 WebView를 통해 일정 시간마다 각 사이트로 이동하게 되고, 매 사이트에 도착할 때마다 그곳을 설명하는 나레이션이 실행된다.
프로그램을 개발하는 과정에서 재밌는 요구사항이 있었다. 이 프로그램에서 방문하는 사이트 중에는 아래와 같은 사이트도 있었다.
https://musiclab.chromeexperiments.com/Spectrogram/
Chrome Music Lab
Music is for everyone. Play with simple experiments that let anyone, of any age, explore how music works.
musiclab.chromeexperiments.com

현재 실행되고 있는 나레이션의 스펙트로그램을 보여주도록 한다.
document.getElementsByClassName('music-box__buttons__button');
<iframe id="experimentFrame"></iframe>
3D Spectrogram
musiclab.chromeexperiments.com

- Realtek High Definition Audio (SST) 드라이버를 설치한다.
- 제어판 > 하드웨어 및 소리 > 소리로 이동한 후, 녹음 장치를 스테레오 믹스로 설정한다.
이렇게 설정한 후 정상적으로 기능이 작동함을 확인할 수 있었다. 하지만 이런 방법에는 아래와 같은 문제점이 있었다.
- 실행 PC에 Realtek 드라이버가 설치되었음을 보장할 수 없다.
- 오디오 입력 장치를 임의로 설정/변경하는 방법을 찾지 못했다. (레지스트리로 접근했지만..)
2-1. 어떤 Element가 이벤트를 처리하는가?
아름다운 minify가 적용되어 덤으로 난독화까지 적용된 모습이었다. 우선 'drop' 이벤트에 대한 처리 방식을 찾아야 했기 때문에, 'drop' 단어를 검색해봤다. 그 결과 아래와 같은 처리 함수가 등록되었음을 확인할 수 있었다.
function (n) {
n.preventDefault(), n.stopPropagation(), e.addClass("pointer-events"), i();
var s = n.originalEvent.dataTransfer;
s && s.files.length && s.items[0] && "audio/midi" !== s.items[0].type
? $.each(s.files, function (n, i) {
i.type.indexOf("audio") > -1
? ($("#loadingMessage").text(i.name), $("#loadingSound").show(0), r(i), e.removeClass("active"), e.removeClass("pointer-events"))
: t.text("Only sound files will work here.");
})
: t.text("Only sound files will work here.");
}
이제 저 처리 함수가 어떤 Element에 등록되었는지 확인해야 했다. 이것을 확인하기 위하여 사용자가 파일을 드롭하는 영역에 'drop' 이벤트 리스너를 추가하였고, 파일을 드랍했을 때 실제로 반응하는 Element가 무엇인지 확인했다.
2-2. 어떻게 파일을 전달할 것인가?
위의 이벤트 처리 함수를 보면 dataTransfer에 담긴 파일을 처리하는 방식임을 알 수 있었다. 그렇다면 이제 audio/mp3 파일을 dataTransfer에 담아서 전달해주기만 하면 될 것 같다. dataTransfer에 대한 내용은 아래에서 확인할 수 있었다.
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations
Drag Operations - Web APIs | MDN
The following describes the steps that occur during a drag and drop operation.
developer.mozilla.org
https://developer.mozilla.org/ko/docs/Web/API/DataTransfer
DataTransfer - Web API | MDN
The DataTransfer object is used to hold the data that is being dragged during a drag and drop operation. It may hold one or more data items, each of one or more data types. For more information about drag and drop, see HTML Drag and Drop API.
developer.mozilla.org
2-3. 아뿔싸! originalEvent가 무엇인가?
jQuery에서는 DOM Event 객체를 jQuery.Event 객체로 래핑하여 사용함을 알 수 있었다.
https://api.jquery.com/category/events/event-object/
Event Object | jQuery API Documentation
The current DOM element within the event bubbling phase. An optional object of data passed to an event method when the current executing handler is bound. The element where the currently-called jQuery event handler was attached. Returns whether event.preve
api.jquery.com