diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
commit | da78a9e329e272dedb2400b79a3bdeebff387d47 (patch) | |
tree | e6ef8aa7c43556f55ddfe031a01cf0a8fa271bfe /files/ko/web/api/html_드래그_앤_드롭_api | |
parent | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (diff) | |
download | translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.gz translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.bz2 translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.zip |
initial commit
Diffstat (limited to 'files/ko/web/api/html_드래그_앤_드롭_api')
-rw-r--r-- | files/ko/web/api/html_드래그_앤_드롭_api/drag_operations/index.html | 343 | ||||
-rw-r--r-- | files/ko/web/api/html_드래그_앤_드롭_api/index.html | 303 |
2 files changed, 646 insertions, 0 deletions
diff --git a/files/ko/web/api/html_드래그_앤_드롭_api/drag_operations/index.html b/files/ko/web/api/html_드래그_앤_드롭_api/drag_operations/index.html new file mode 100644 index 0000000000..122e835b75 --- /dev/null +++ b/files/ko/web/api/html_드래그_앤_드롭_api/drag_operations/index.html @@ -0,0 +1,343 @@ +--- +title: Drag Operations +slug: Web/API/HTML_드래그_앤_드롭_API/Drag_operations +translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations +--- +<p>{{DefaultAPISidebar("HTML Drag and Drop API")}}</p> + +<p>다음은 드래그 & 드랍(drag & drop) 동작 실행 시 각 단계에 대한 설명입니다.</p> + +<p class="note">이 문서에 설명된 드래그 동작은 {{domxref("DataTransfer")}} 인터페이스를 사용합니다. 이 문서에서는 {{domxref("DataTransferItem")}} 인터페이스나 {{domxref("DataTransferItemList")}} 인터페이스를 사용하지 않습니다.</p> + +<h2 id="draggableattribute" name="draggableattribute">Draggable 속성</h2> + +<p>웹 페이지 안에서 특정 상황에 기본 드래그(default drag) 행위가 사용될 경우가 있습니다. 선택된 텍스트(text selections), 이미지 또는 링크가 여기에 포함됩니다. 이미지나 링크가 드래그될 때, 이미지나 링크의 URL이 드래그 데이터(drag data)로 설정되고 드래그가 시작됩니다. 다른 요소의 경우, 기본 드래그가 발생할 선택(selections)에 포함되어 있어야 합니다(For other elements, they must be part of a selection for a default drag to occur). 이 효과를 보기 위해서는 웹 페이지의 어떤 영역을 선택하고 마우스를 클릭한 채로 드래그하면 됩니다. 드래그가 발생할 때 마우스 포인터로 선택 영역에 대한 OS별 렌더링이 표시됩니다. 이 행위는 기본 드래그 행위인 경우에만 발생하는 것으로 드래그되는 데이터를 조정할 리스너가 없는 경우에는 작동하지 않습니다.</p> + +<p>HTML에서 이미지나 링크 그리고 선택(selections)에 대한 기본 행위를 제외한 나머지 요소는 기본적으로 드래그되지 않습니다. <a href="/en-US/docs/Mozilla/Tech/XUL">XUL</a>에서는 모든 요소가 드래그 가능합니다.</p> + +<p>다른 HTML 요소를 드래그할 수 있게 하려면 세 가지가 이루어져야 합니다:</p> + +<ul> + <li>드래그가 가능하도록 만들고자 하는 요소에 대한 <code>{{htmlattrxref("draggable")}}</code> 속성이 <code>true</code>로 설정되어야 합니다.</li> + <li><code>{{event("dragstart")}}</code> 이벤트에 대한 리스너를 추가합니다.</li> + <li>위에서 정의한 리스너에 {{domxref("DataTransfer.setData","Set the drag data")}}를 설정합니다.</li> +</ul> + +<p>컨텐츠의 일부 영역을 드래그할 수 있도록 만드는 예제는 다음과 같습니다.</p> + +<pre class="brush: html"><div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')"> + This text <strong>may</strong> be dragged. +</div> +</pre> + +<p>요소를 드래그할 수 있게 하기 위해서는 <code>{{htmlattrxref("draggable")}}</code> 속성이 true로 설정되어야 합니다. 이 속성이 생략되거나 false로 설정되면 해당 요소는 드래그할 수 없으며, 대신 텍스트가 선택됩니다. <code>{{htmlattrxref("draggable")}}</code> 속성은 이미지나 링크를 포함한 어떤 요소에서도 사용할 수 있습니다. 하지만, 이미지나 링크에 대해서는 기본값이 true로 설정되어 있으므로 이들 요소에 대해 드래깅할 수 없게 만들 경우에만 <code>{{htmlattrxref("draggable")}}</code> 속성의 값을 false로 설정하면 됩니다.</p> + +<p>어떤 요소가 드래그 가능한 경우, 해당 요소 내의 텍스트나 다른 요소는 마우스를 클릭하고 드래그하는 통상적인 방식으로는 선택할 수 없게 됩니다. 대신, 사용자가 <kbd>alt</kbd> 키를 누른채로 마우스로 텍스트를 선택하거나 키보드를 이용해 선택할 수 있습니다.</p> + +<p>XUL 요소에 대해서는 <code>{{htmlattrxref("draggable")}}</code> 속성을 사용할 필요가 없으며, 모든 XUL 요소는 드래그가 가능합니다.</p> + +<pre class="brush: html"><button label="Drag Me" ondragstart="event.dataTransfer.setData('text/plain', 'Drag Me Button');"> +</pre> + +<h2 id="dragstart" name="dragstart">드래그 작업 시작</h2> + +<p>이 예제에서는 <code>{{domxref("GlobalEventHandlers.ondragstart","ondragstart")}}</code> 속성을 이용하여 {{event("dragstart")}} 이벤트에 대한 리스너를 추가합니다.</p> + +<pre class="brush: html"><div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')"> + This text <strong>may</strong> be dragged. +</div> +</pre> + +<p>사용자가 드래그를 시작할 때, {{event("dragstart")}} 이벤트가 발생합니다. 이 예제에서는 드래그할 요소에 {{event("dragstart")}} 리스너가 추가되었습니다; 하지만, 대부분의 다른 이벤트가 그렇듯이 상위 요소에서 드래그 이벤트를 포착할 수 있습니다. {{event("dragstart")}} 이벤트 내에서 아래에서 설명하는 바와 같이 피드백 이미지(feedback image)나 드래그 효과와 그리고 드래그 데이터를 명시할 수 있습니다. 기본 이미지나 드래그 효과는 대부분의 상황에 적합하게 되어 있으며, 드래그 데이터만 필요합니다.</p> + +<h2 id="dragdata" name="dragdata">데이터 드래그</h2> + +<p>모든 {{domxref("DragEvent","drag events")}}는 드래그 데이터를 가지고 있는 {{domxref("DragEvent.dataTransfer","dataTransfer")}}라는 속성이 존재합니다 (<code>dataTransfer</code>는 {{domxref("DataTransfer")}} 객체입니다).</p> + +<p>드래그가 발생할 때, 데이터는 어떤 것이 드래그되는지를 구분할 수 있는 드래그와 연관되어야 합니다(When a drag occurs, data must be associated with the drag which identifies <em>what</em> is being dragged). 예를 들어, 선택된 텍스트가 드래그될 경우 드래그 데이터 항목에 연관된 데이터는 텍스트 자체입니다. 이와 유사하게, 웹 페이지 상의 링크가 드래그될 경우에 드래그 데이터 항목은 링크의 URL이됩니다.</p> + +<p>{{domxref("DataTransfer","drag data")}}는 두 가지 정보를 담고 있는데, 데이터의 유형(또는 형식)과 데이터 값입니다. 형식은 (텍스트 데이터에 해당하는 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#text" title="text/plain">text/plain</a>과 같은) 형식 문자열(type string) 값이고, 값은 텍스트의 문자열입니다. 드래그가 시작되면, 데이터와 형식을 제공하는 데이터를 추가해야 합니다. 드래그되는 동안, <code>{{event("dragenter")}}</code> 이벤트와 <code>{{event("dragover")}}</code> 이벤트에 대한 이벤트 리스너에서 드래그되는 데이터의 형식을 사용해 드랍이 허용되는지 확인할 수 있습니다. 예를 들어, 링크가 허용되는 드랍 대상(drop target)은 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#link" title="text/uri-list">text/uri-list</a> 형식의 링크인지 확인합니다. 드랍 이벤트 동안 리스너는 드래그 대상(being dragged)으로부터 데이터를 추출해 드랍되는 위치에 삽입합니다.</p> + +<p>{{domxref("DataTransfer","drag data's")}}의 {{domxref("DataTransfer.types","types")}} 속성은 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#text" title="text/plain">text/plain</a> or <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#image" title="image/jpeg">image/jpeg</a>과 같은 {{domxref("DOMString")}} MIME-type 목록을 반환홥니다. 여러분은 자신만의 형식을 만들 수도 있습니다. 가장 흔하게 사용되는 형식은 권장 드래그 데이터 형식(<a href="/en-US/docs/DragDrop/Recommended_Drag_Types" title="/en-US/docs/DragDrop/Recommended_Drag_Types">Recommended Drag Types</a>)에서 소개하고 있습니다.</p> + +<p>드래그에는 여러 가지 다른 형식의 데이터 항목이 포함될 수 있습니다. 이를 통해 사용자 정의 형식(custom types)과 같은 보다 특정한 형식의 데이터를 주로 제공하지만, 특정한 유형을 지원하지 않는 드롭 대상에 대해 대체 데이터(fallback data)를 제공할 수도 있습니다. <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#text" title="text/plain">text/plain</a> 형식의 일반적인 텍스트 데이터가 가장 단순한 형식의 데이터일 것입니다.이 형식의 데이터는 단순히 텍스트 형식으로 표시될 것입니다.</p> + +<p>{{domxref("DragEvent.dataTransfer","dataTransfer")}} 내에 드래그 데이터 항목(drag data item)을 설정하기 위해서는 {{domxref("DataTransfer.setData","setData()")}} 메서드를 이용합니다. 이 메서드는 각각 데이터 형식과 데이터 값인 두 개의 인자가 필요합니다. 예를 들어:</p> + +<pre class="brush: js">event.dataTransfer.setData("text/plain", "Text to drag"); +</pre> + +<p>이 경우, 데이터 값은 "Text to drag"이고 형식은 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#text" title="text/plain">text/plain</a>입니다.</p> + +<p>여러 형식의 데이터를 제공할 수도 있습니다. 이를 위해서는 서로 다른 형식으로 {{domxref("DataTransfer.setData","setData()")}} 메서드를 여러 번 호출합니다. 이 때, 가장 세부적인 형식에서 덜 세부적인 형식의 순으로 호출해야 합니다.</p> + +<pre class="brush: js">var dt = event.dataTransfer; +dt.setData("application/x-bookmark", bookmarkString); +dt.setData("text/uri-list", "http://www.mozilla.org"); +dt.setData("text/plain", "http://www.mozilla.org"); +</pre> + +<p>여기서 데이터는 세가지 유형으로 추가됩니다. 첫번째 형식의 'application2x-bookmark'는 사용자 지정 형식입니다. 다른 응용 프로그램에서는 이 형식을 지원하지 않지만 동일한 사이트 또는 응용 프로그램의 영역 간 드래그할 경우, 이 사용자 지정 형식을 사용할 수 있습니다. 또한 다른 형식의 데이터를 제공함으로써 덜 세부적인 형태로 다른 애플리케이션으로의 드래그도 지원할 수 있습니다. 다른 형식이 하나의 URL또는 텍스트 형식만 제공할 때, 'application2x-bookmark' 형식은 해당 어플리케이션 내에서 사용될 경우 더 상세한 데이터를 제공할 수 있습니다</p> + +<p>이 예제에서 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#link" title="text/uri-list">text/uri-list</a>와 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#text" title="text/plain">text/plain</a>은 동일한 데이터를 담고있음에 주목하시기 바랍니다. 이렇게 해도 되지만, 꼭 이럴 필요는 없습니다.</p> + +<p>동일한 형식으로 데이터를 두 번 추가하려고 하면 새로운 데이터가 기존 데이터를 대체하지만 형식 목록 내에서 이전 데이터(old data)와 같은 위치에 있게 됩니다.</p> + +<p>{{domxref("DataTransfer.clearData","clearData()")}} 메서드를 이용해 해당 데이터를 지울 수 있는데, 이 메서드는 지우고자 하는 데이터의 형식을 인자로 가집니다.</p> + +<pre class="brush: js">event.dataTransfer.clearData("text/uri-list"); +</pre> + +<p>{{domxref("DataTransfer.clearData","clearData()")}} 메서드에 대한 형식 인자는 선택적입니다. 형식을 지정하지 않으면 모든 형식과 연관된 데이터가 지워집니다. 드래그할 때, 드래그 데이터 항목이 없거나 이후에 모든 항목이 삭제되면 드래그가 발생하지 않습니다.</p> + +<h2 id="dragfeedback" name="dragfeedback">드래그 피드백 이미지 설정</h2> + +<p>드래그가 발생할 때, 드래그 대상("{{event("dragstart")}}" 이벤트가 발생한 요소)으로부터 반투명한 이미지가 생성되고 드래그 하는 동안 마우스 포인터를 따라 움직입니다. 이 이미지는 자동으로 생성되며, 따로 생성할 필요가 없습니다. 하지만, {{domxref("DataTransfer.setDragImage","setDragImage()")}}를 이용해 사용자 정의 드래그 피드백 이미지를 지정할 수 있습니다.</p> + +<pre class="brush: js">event.dataTransfer.setDragImage(image, xOffset, yOffset); +</pre> + +<p>세 개의 인자는 필수입니다. 첫 번째 인자는 이미지에 대한 참조(reference)입니다. 이 참조는 일반적으로 이미지에 대한 참조이나 캔버스(canvas)나 다른 요소를 지정할 수도 있습니다. 피드백 이미지는 단순하게 화면에 표시된 이미지의 모양으로부터 생성되지만, 이미지의 경우 원래 크기로 그려집니다. {{domxref("DataTransfer.setDragImage","setDragImage()")}} 메서드의 두 번째와 세 번째 인자는 마우스 포인터에 대해 상대적인 옵셋(offsets)으로 이미지가 나타날 위치를 의미합니다.</p> + +<p>문서 내에 있지 않은 이미지나 캔버스를 사용하는 것 역시 가능합니다. 이 기법은 다음의 예제와 같이 캔버스 요소를 이용해 드래그 이미지를 사용자 정의 형태로 그리고자 할 때 유용합니다:</p> + +<pre class="brush: js">function dragWithCustomImage(event) { + var canvas = document.createElementNS("http://www.w3.org/1999/xhtml","canvas"); + canvas.width = canvas.height = 50; + + var ctx = canvas.getContext("2d"); + ctx.lineWidth = 4; + ctx.moveTo(0, 0); + ctx.lineTo(50, 50); + ctx.moveTo(0, 50); + ctx.lineTo(50, 0); + ctx.stroke(); + + var dt = event.dataTransfer; + dt.setData('text/plain', 'Data to Drag'); + dt.setDragImage(canvas, 25, 25); +} +</pre> + +<p>이 예제에서, 드래그 이미지를 표시할 캔버스를 하나 생성합니다. 캔버스는 너비가 와 높이가 모두 50 픽셀이고, 마우스 포인터가 이미지의 중앙에 위치하도록 옵셋(offsets)을 너비와 높이의 절반(25)으로 설정했습니다.</p> + +<p>{{h2_gecko_minversion("Using XUL panels as drag images", "9.0")}}</p> + +<p>Gecko 개발자일 경우 (Mozilla 어플리케이션 개발자든 add-on 개발자든 상관 없이), Gecko 9.0 {{geckoRelease("9.0")}}에 드래그 피드백 이미지로 XUL {{XULElem("panel")}} 요소를 사용할 수 있도록 하는 지원이 추가되었습니다. 간단히 {{XULElem("panel")}} 요소를 {{domxref("DataTransfer.setDragImage","setDragImage()")}} 메서드로 전달하기만 하면 됩니다.</p> + +<p>다음 XUL {{XULElem("panel")}}를 살펴보시기 바랍니다:</p> + +<pre class="brush: xml"><<span class="start-tag">panel</span><span class="attribute-name"> id</span>=<span class="attribute-value">"panel" </span><span class="attribute-name">style</span>=<span class="attribute-value">"opacity: 0.6</span><span class="attribute-value">"</span>> + <<span class="start-tag">description</span><span class="attribute-name"> id</span>=<span class="attribute-value">"pb"</span>>Drag Me</<span class="end-tag">description</span>> +</<span class="end-tag">panel</span>> + +<<span class="start-tag">vbox</span><span class="attribute-name"> align</span>=<span class="attribute-value">"start" </span><span class="attribute-name">style</span>=<span class="attribute-value">"border: 1px solid black;" </span><span class="attribute-name">ondragstart</span>=<span class="attribute-value">"startDrag(event)"</span>> + <<span class="start-tag">description</span>>Drag Me</<span class="end-tag">description</span>> +</<span class="end-tag">vbox</span>> +</pre> + +<p>위의 예에서 사용자가 {{XULElem("vbox")}}를 클릭하고 드래그하기 시작하면, 아래의 <code>startDrag()</code> 함수가 호출됩니다.</p> + +<pre class="brush: js"><span class="cdata">function startDrag(event) { + event.dataTransfer.setData("text/plain", "<strong>Body</strong>"); + event.dataTransfer.setDragImage(document.getElementById("panel"), 20, 20); +}</span> +</pre> + +<p>이 함수는 해당 패널을 드래그 이미지로 사용하고, HTML 형식의 "<strong>Body</strong>"을 데이터로 가집니다. 텍스트 편집기에 패널을 드랍하면 "<strong>Body</strong>"라는 텍스트가 드랍된 위치에 삽입됩니다.</p> + +<h2 id="drageffects" name="drageffects">드래그 효과</h2> + +<p>드래그할 때, 여러 가지 작업이 수행될 수 있습니다. <code>copy</code> 작업은 드래그되는 데이터가 현재 위치에서 드랍되는 위치로 복사될 것임을 나타냅니다. <code>move</code> 작업은 드래그되는 데이터가 이동될 것임을 나타내고, <code>link</code> 작업은 특정 형태의 관계(relationship)나 연결(connection)이 소스와 드랍되는 위치 사이에 생성될 것임을 나타냅니다.</p> + +<p>드래그 소스(drag source)에 대해 <code>{{event("dragstart")}}</code> 이벤트 리스너의 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 설정함으로써, 이 세 가지 작업 중 어떤 것을 허용할 것인지를 지정할 수 있습니다.</p> + +<pre class="brush: js">event.dataTransfer.effectAllowed = "copy"; +</pre> + +<p>이 예제에서는, 복사만 허용됩니다. 다양한 방식으로 값을 조합할 수 있습니다:</p> + +<dl> + <dt>none</dt> + <dd>어떤 작업도 허용하지 않음.</dd> + <dt>copy</dt> + <dd>복사만 허용</dd> + <dt>move</dt> + <dd>이동만 허용</dd> + <dt>link</dt> + <dd>연결만 허용</dd> + <dt>copyMove</dt> + <dd>복사 또는 이동만 허용</dd> + <dt>copyLink</dt> + <dd>복사 또는 연결만 허용</dd> + <dt>linkMove</dt> + <dd>연결 또는 이동만 허용</dd> + <dt>all</dt> + <dd>복사, 이동 및 연결 모두 허용</dd> +</dl> + +<p>이 값들은 반드시 위에 나열한 것과 정확하게 일치해야 함에 유의하시기 바랍니다. 예를 들어, {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 <code>copyMove</code>로 설정하면 복사와 이동 작업이 허용되나 연결(link) 작업은 금지됩니다. {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 변경하지 않으면 'all' 값과 마찬가지로 어떤 작업도 허용됩니다. 따라서, 특정한 유형의 작업을 제외시키고 싶지 않다면 이 속성을 조정할 필요가 없습니다.</p> + +<p>드래그 작업 중에 <code>{{event("dragenter")}}</code> 또는 <code>{{event("dragover")}}</code> 이벤트에 대한 리스너는 어떤 작업이 허용되어 있는지 알기 위해 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 확인할 수 있습니다. 관련된 속성으로, {{domxref("DataTransfer.dropEffect","dropEffect")}}는 이들 이벤트 중 하나에서 수행되어야 하는 단일 작업을 지정하기 위해 설정되어야 할 속성입니다. {{domxref("DataTransfer.dropEffect","dropEffect")}}에 유효한 값은 <code>none</code>, <code>copy</code>, <code>move</code>, 또는 <code>link</code>입니다. 이 속성에 값의 조합은 허용되지 않습니다.</p> + +<p><code>{{event("dragenter")}}</code>나 <code>{{event("dragover")}}</code> 이벤트가 발생하면 사용자가 요청하는 효과로 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성이 초기화됩니다. 사용자는 한정자 키를 눌러 원하는 효과로 수정할 수 있습니다. 플랫폼에 따라 정확한 키가 달라질 수 있지만, 일반적으로 쉬프트(Shift)와 컨트롤(Control) 키가 복사하기, 이동하기, 연결하기 간 전환에 사용됩니다. 마우스 포인터를 원하는 작업을 나타내도록 변경할 수 있습니다; 예를 들어, 복사 작업에 대해서는 마우스 포인터 옆에 더하기 기호가 표시된 커서가 나타날 수 있습니다.</p> + +<p><code>{{event("dragenter")}}</code> 또는 <code>{{event("dragover")}}</code> 이벤트가 발생하는 동안 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 변경할 수 있는데, 예를 들자면, 특정 작업만 지원되는 특수한 드랍 대상(drop target)일 경우가 그렇습니다. {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 수정하여 사용자 효과(user effect)를 오버라이드하여 특정한 드랍 작업이 발생하게 할 수 있습니다. 이 효과는 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성에 열거된 것 중의 하나 이어야 함에 유의하시기 바랍니다. 그렇지 않을 경우, 허용되는 대체 값으로 설정되게 됩니다.</p> + +<pre class="brush: js">event.dataTransfer.dropEffect = "copy"; +</pre> + +<p>이 예제에서는 복사가 수행될 효과입니다.</p> + +<p>이 경우에는 이벤트를 취소하지 않는 것이 좋지만 <code>none</code> 값을 사용하여 이 위치에서 드롭이 허용되지 않음을 나타낼 수 있습니다.</p> + +<p><code>{{event("drop")}}</code>와 <code>{{event("dragend")}}</code> 이벤트 내에서{{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 확인하면 최종적으로 어떤 효과가 선택되었는지를 알 수 있습니다. 선택된 효과가 "move"였다면, <code>{{event("dragend")}}</code> 이벤트 내에서 드래그 소스의 원본 데이터가 삭제되어야 합니다.</p> + +<h2 id="droptargets" name="droptargets">드랍 대상 지정하기</h2> + +<p><code>{{event("dragenter")}}</code>와 <code>{{event("dragover")}}</code> 이벤트에 대한 리스너는 유효한 드랍 대상인지, 즉 드래그된 아이템이 드랍될 수 있는 곳인지를 나타내는데 사용할 수 있습니다. 웹 페이지 또는 어플리케이션의 대부분의 영역은 데이터를 드랍할 수 있는 유효한 영역이 아닙니다. 따라서, 이들 이벤트에 대한 기본적인 처리는 드랍을 허용하지 않는 것입니다.</p> + +<p>드랍을 허용하길 원한다면, 해당 이벤트를 취소하는 기본 처리를 막아야 합니다. 속성 정의(attribute-defined) 이벤트 리스너로부터 <code>false</code>를 반환 받거나 해당 이벤트의 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하면 됩니다. 후자는 별도의 스크립트에 정의된 함수에 더 적합합니다.</p> + +<pre class="brush: html"><div ondragover="return false"> +<div ondragover="event.preventDefault()"> +</pre> + +<p><code>{{event("dragenter")}}</code> and <code>{{event("dragover")}}</code> 두 이벤트 모두에서 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하는 것은 그 위치에 드랍이 허용되는 것을 나타냅니다. 하지만, 일반적으로 특정한 상황에서만, 예를 들자면 링크가 드래그될 때만 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하길 원할 것입니다. 이렇게 하기 위해서는 조건을 확인하여 조건이 충족될 때에만 해당 이벤트를 취소하는 함수를 호출합니다. 조건이 충족되지 않을 경우, 이벤트를 취소하지 않으면 사용자가 마우스 버튼을 놓더라도 드랍은 발생하지 않을 것입니다.</p> + +<p>data transfer의 드래그 데이터 형식에 따라 드랍을 허용하거나 기각하는 경우가 대부분일 것입니다(예를 들어, 이미지나 링크를 허용하거나 둘 다 허용하는 경우). 이렇게 하기 위해서는 이벤트의 {{domxref("DragEvent.dataTransfer","dataTransfer")}} 속성의 {{domxref("DataTransfer.types","types")}} 속성을 확인합니다. {{domxref("DataTransfer.types","types")}} 속성은 드래그가 시작될 때 추가된 형식 문자열의 배열을 반환하는데, 그 순서는 가장 세부적인 형식에서 가장 덜 세부적인 형식의 순서입니다.</p> + +<pre class="brush: js">function contains(list, value) { + for( var i = 0; i < list.length; ++i ) { + if(list[i] === value) return true; + } + return false; +} + +function doDragOver(event) { + var isLink = contains( event.dataTransfer.types, "text/uri-list"); + if (isLink) { + event.preventDefault(); + } +}</pre> + +<p>이 예제에서 형식 목록 내에 <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#link" title="text/uri-list">text/uri-list</a> 형식이 존재하는지 확인하기 위해 <code>contains</code> 메서드를사용합니다. 존재할 경우에는 드랍을 허용하기 위해 이벤트가 취소될 것입니다. 드래그 데이터가 링크를 포함하지 않았다면, 해당 이벤트는 취소되지 않을 것이고 그 위치에 대한 드랍이 발생하지 않을 것입니다.</p> + +<p>수행되어야 하는 작업 형식을 더 세부적으로 설정하길 원한다면, {{domxref("DataTransfer.effectAllowed","effectAllowed")}}나 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 각각 설정하거나 동시에 둘 다를 설정하고 싶을 것입니다. 두 속성을 변경하더라도 해당 이벤트를 취소하지 않으면 아무런 영향이 없을 것입니다.</p> + +<h3 id="Updates_to_DataTransfer.types">Updates to DataTransfer.types</h3> + +<p>최신 스펙에는 {{domxref("DataTransfer.types")}}이 {{domxref("DOMStringList")}}(이 속성은 Fiirefox 52 이상에서 지원됨)이 아닌 {{domxref("DOMString")}} 형식의 고정배열(fronzen array)을 반환하도록 명시하고 있음에 유의하시기 바랍니다.</p> + +<p>그 결과로, <a href="/en-US/docs/Web/API/Node/contains">contains</a> 메서드는 해당 속성에 대해 더 이상 동작하지 않으며; 특정 형식의 데이터가 제공되는지 확인하기 위해서는 다음 코드와 같이 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">includes</a> 메서드를 사용해야 합니다:</p> + +<pre class="brush: js">if ([...event.dataTransfer.types].includes('text/html')) { + // Do something +}</pre> + +<p>일부 특성 검출(feature detection)을 이용해 <code>types</code>에 대해 어떤 메서드가 지원되는지를 판별하고 적절하게 코드를 실행할 수 있습니다.</p> + +<h2 id="dropfeedback" name="dropfeedback">Drop Feedback</h2> + +<p>There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property. Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.</p> + +<p>However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the <code>-moz-drag-over</code> CSS pseudoclass on a drop target.</p> + +<pre class="brush: css">.droparea:-moz-drag-over { + border: 1px solid black; +} +</pre> + +<p>In this example, the element with the class <code>droparea</code> will receive a 1 pixel black border while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the <code>{{event("dragenter")}}</code> event. Note that you must cancel the <code>{{event("dragenter")}}</code> event for this pseudoclass to apply, as this state is not checked for the <code>{{event("dragover")}}</code> event.</p> + +<p>For more complex visual effects, you can also perform other operations during the <code>{{event("dragenter")}}</code> event, for example, by inserting an element at the location where the drop will occur. For example, this might be an insertion marker or an element that represents the dragged element in its new location. To do this, you could create an <a href="/en-US/docs/XUL/image" title="image">image</a> or <a href="/en-US/docs/XUL/separator" title="separator">separator</a> element, for example, and simply insert it into the document during the <code>{{event("dragenter")}}</code> event.</p> + +<p>The <code>{{event("dragover")}}</code> event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a <code>{{event("dragover")}}</code> event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.</p> + +<p>Finally, the <code>{{event("dragleave")}}</code> event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the <code>-moz-drag-over</code> pseudoclass will be removed automatically. The <code>{{event("dragleave")}}</code> event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.</p> + +<h2 id="drop" name="drop">Performing a Drop</h2> + +<p>When the user releases the mouse, the drag and drop operation ends. If the mouse was released over an element that is a valid drop target, that is, one that cancelled the last <code>{{event("dragenter")}}</code> or <code>{{event("dragover")}}</code> event, and then the drop will be successful, and a <code>{{event("drop")}}</code> event will fire at the target. Otherwise, the drag operation is cancelled, and no <code>{{event("drop")}}</code> event is fired.</p> + +<p>During the <code>{{event("drop")}}</code> event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.</p> + +<p>As with all drag-related events, the event's <code>{{domxref("DataTransfer","dataTransfer")}}</code> property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.</p> + +<pre class="brush: js">function onDrop(event) { + var data = event.dataTransfer.getData("text/plain"); + event.target.textContent = data; + event.preventDefault(); +} +</pre> + +<p>The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a <code>{{event("dragover")}}</code> event.</p> + +<p>In the example here, once we have retrieved the data, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a <code>p</code> or <code>div</code> element.</p> + +<p>In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop so that the default browser handling does not handle the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.</p> + +<p>You can retrieve other types of data as well. If the data is a link, it should have the type <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#link" title="text/uri-list">text/uri-list</a>. You could then insert a link into the content.</p> + +<pre class="brush: js">function doDrop(event) { + var lines = event.dataTransfer.getData("text/uri-list").split("\n"); + for (let line of lines) { + if (line.startsWith("#")) + continue; + + let link = document.createElement("a"); + link.href = line; + link.textContent = line; + event.target.appendChild(link); + } + event.preventDefault(); +} +</pre> + +<p>This example inserts a link from the dragged data. As you might be able to guess from the name, the <a href="/en-US/docs/DragDrop/Recommended_Drag_Types#link" title="text/uri-list">text/uri-list</a> type actually may contain a list of URLs, each on a separate line. In this code, we use the <a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/split" title="split">split</a> to split the string into lines, then iterate over the list of lines, inserting each as a link into the document. Note also that we skip links starting with a number sign (#) as these are comments.</p> + +<p>For simple cases, you can use the special type <code>URL</code> just to retrieve the first valid URL in the list. For example:</p> + +<pre class="brush: js">var link = event.dataTransfer.getData("URL"); +</pre> + +<p>This eliminates the need to check for comments or iterate through lines yourself; however, it is limited to only the first URL in the list.</p> + +<p>The <code>URL</code> type is a special type used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.</p> + +<p>Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In this example, three formats are supported by a drop target.</p> + +<p>The following example returns the data associated with the best-supported format:</p> + +<pre class="brush: js">function doDrop(event) { + var types = event.dataTransfer.types; + var supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"]; + types = supportedTypes.filter((value) => types.includes(value)); + if (types.length) + var data = event.dataTransfer.getData(types[0]); + event.preventDefault(); +} +</pre> + +<p>This method relies on JavaScript functionality available in Firefox 3. However, the code could be adjusted to support other platforms.</p> + +<h2 id="dragend" name="dragend">Finishing a Drag</h2> + +<p>Once the drag is complete, a <code>{{event("dragend")}}</code> event is fired at the source of the drag (the same element that received the <code>{{event("dragstart")}}</code> event). This event will fire if the drag was successful[1] or if it was cancelled. However, you can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine what drop operation occurred.</p> + +<p>If the {{domxref("DataTransfer.dropEffect","dropEffect")}} property has the value <code>none</code> during a <code>{{event("dragend")}}</code>, then the drag was cancelled. Otherwise, the effect specifies which operation was performed. The source can use this information after a move operation to remove the dragged item from the old location. The {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} property will be set to true if the user cancelled the drag (by pressing Escape), and false if the drag was cancelled for other reasons such as an invalid drop target, or if it was successful.</p> + +<p>A drop can occur inside the same window or over another application. The <code>{{event("dragend")}}</code> event will always fire regardless. The event's {{domxref("MouseEvent.screenX","screenX")}} and {{domxref("MouseEvent.screenY","screenY")}} properties will be set to the screen coordinate where the drop occurred.</p> + +<p>After the <code>{{event("dragend")}}</code> event has finished propagating, the drag and drop operation is complete.</p> + +<p>[1] In Gecko, {{event("dragend")}} is not dispatched if the source node is moved or removed during the drag (e.g. on drop or {{event("dragover")}}). <a class="external" href="https://bugzilla.mozilla.org/show_bug.cgi?id=460801" title="New D&D API: dragend is not dispatched if the source node was moved or removed during the drag session">bug 460801</a></p> + +<h2 id="See_also" name="See_also">See also</h2> + +<ul> + <li><a class="internal" href="/Web/API/HTML_Drag_and_Drop_API" title="HTML Drag and Drop API">HTML Drag and Drop API (Overview)</a></li> + <li><a class="internal" href="/Web/Guide/HTML/Dragging_and_Dropping_Multiple_Items" title="Dragging and Dropping Multiple Items">Dragging and Dropping Multiple Items</a></li> + <li><a class="internal" href="/Web/Guide/HTML/Recommended_Drag_Types" title="Recommended Drag Types">Recommended Drag Types</a></li> + <li><a href="https://html.spec.whatwg.org/multipage/interaction.html#dnd" title="Drag and Drop Standard">HTML5 Living Standard: Drag and Drop</a></li> +</ul> diff --git a/files/ko/web/api/html_드래그_앤_드롭_api/index.html b/files/ko/web/api/html_드래그_앤_드롭_api/index.html new file mode 100644 index 0000000000..70a4295284 --- /dev/null +++ b/files/ko/web/api/html_드래그_앤_드롭_api/index.html @@ -0,0 +1,303 @@ +--- +title: HTML 드래그 앤 드롭 API +slug: Web/API/HTML_드래그_앤_드롭_API +tags: + - HTML5 + - XUL + - 가이드 + - 개요 + - 고급 + - 드래그 앤 드롭 + - 이벤트 +translation_of: Web/API/HTML_Drag_and_Drop_API +--- +<p>{{DefaultAPISidebar("HTML 드래그 앤 드롭 API")}}</p> + +<p><span class="seoSummary">HTML 드래그 앤 드롭 인터페이스는 파이어폭스와 다른 브라우저에서 어플리케이션이 드래그 앤 드롭 기능을 사용하게 해줍니다.</span> 이 기능을 이용해 사용자는 <em>draggable</em> 요소를 마우스로 선택해 <em>droppable</em> 요소로 드래그하고, 마우스 버튼에서 손을 뗌으로써 요소를 드롭할 수 있습니다. 드래그하는 동안 draggable 요소는 반투명한 채로 마우스 포인터를 따라다닙니다.</p> + +<p>웹 사이트나 확장 기능, XUL 어플리케이션을 위해, 다양한 요소를 draggable 요소로 만들 수 있고, 이벤트에 대한 draggable 요소의 반응들을 만들어내거나 droppable 요소를 자유자재로 만들 수 있습니다.</p> + +<p>이 문서는 HTML 드래그 앤 드롭에 대한 전반적인 개요입니다. 인터페이스에 대한 설명과 드래그 앤 드롭 기능을 어플리케이션에서 사용하기 위한 기본적인 절차, 인터페이스의 상호 운용성에 대한 요약 등이 이 문서에 담겨있습니다.</p> + +<h2 id="드래그_이벤트">드래그 이벤트</h2> + +<p>HTML 드래그 앤 드롭은 {{domxref("Event","DOM event model")}} 과 <em>{{domxref("DragEvent","drag events")}} </em>를<em> </em> {{domxref("MouseEvent","mouse events")}} 로부터 상속받습니다. 보통 드래그는 사용자가 draggable 요소를 마우스로 선택하고, 마우스 포인터를 droppable 요소로 가져가 마우스 버튼을 때는 것으로 이루어집니다. 드래그하는 도중에 많은 이벤트가 발생하고, 몇몇 이벤트는 여러번 발생하기도 합니다. ( {{event("drag")}}와 {{event("dragover")}}).</p> + +<p>모든 <a href="/en-US/docs/Web/API/DragEvent#Event_types">드래그 이벤트</a>는 <a href="/en-US/docs/Web/API/DragEvent#GlobalEventHandlers">글로벌 이벤트 핸들러</a>와 연결되어 있습니다. 각 드래그 이벤트와 드래그 전역 속성은 참조 문서를 가지고 있습니다. 아래 표는 각 이벤트에 대한 간략한 설명과 참조 문서로의 링크를 담고 있습니다.</p> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">이벤트</th> + <th scope="col">이벤트 핸들러</th> + <th scope="col">설명</th> + </tr> + <tr> + <td>{{domxref('Document/drag_이벤트', 'drag')}}</td> + <td>{{domxref('GlobalEventHandlers.ondrag','ondrag')}}</td> + <td>요소나 텍스트 블록을 드래그 할 때 발생한다.</td> + </tr> + <tr> + <td>{{event('dragend')}}</td> + <td>{{domxref('GlobalEventHandlers.ondragend','ondragend')}}</td> + <td> + <p>드래그를 끝냈을 때 발생한다. (마우스 버튼을 떼거나 ESC 키를 누를 때) (<a href="/en-US/docs/DragDrop/Drag_Operations#dragend">드래그 끝내기</a>를 보시오)</p> + </td> + </tr> + <tr> + <td>{{event('dragenter')}}</td> + <td>{{domxref('GlobalEventHandlers.ondragenter','ondragenter')}}</td> + <td> + <p>드래그한 요소나 텍스트 블록을 적합한 드롭 대상위에 올라갔을 때 발생한다. (<a href="/en-US/docs/DragDrop/Drag_Operations#droptargets">드롭 대상 지정하기</a>를 보시오.)</p> + </td> + </tr> + <tr> + <td>{{event('dragexit')}}</td> + <td>{{domxref('GlobalEventHandlers.ondragexit','ondragexit')}}</td> + <td> + <p>요소가 더 이상 드래그의 직접적인 대상이 아닐 때 발생한다.</p> + </td> + </tr> + <tr> + <td>{{event('dragleave')}}</td> + <td>{{domxref('GlobalEventHandlers.ondragleave','ondragleave')}}</td> + <td> + <p>드래그하는 요소나 텍스트 블록이 적합한 드롭 대상에서 벗어났을 때 발생한다.</p> + </td> + </tr> + <tr> + <td>{{event('dragover')}}</td> + <td>{{domxref('GlobalEventHandlers.ondragover','ondragover')}}</td> + <td> + <p>요소나 텍스트 블록을 적합한 드롭 대상 위로 지나갈 때 발생한다. (매 수백 밀리초마다 발생한다.)</p> + </td> + </tr> + <tr> + <td>{{event('dragstart')}}</td> + <td>{{domxref('GlobalEventHandlers.ondragstart','ondragstart')}}</td> + <td> + <p>사용자가 요소나 텍스트 블록을 드래그하기 시작했을 때 발생한다. (<a href="/en-US/docs/DragDrop/Drag_Operations#dragstart">드래그 시작하기</a>를 보시오.)</p> + </td> + </tr> + <tr> + <td>{{event('drop')}}</td> + <td>{{domxref('GlobalEventHandlers.ondrop','ondrop')}}</td> + <td> + <p>요소나 텍스트 블록을 적합한 드롭 대상에 드롭했을 때 발생한다. (<a href="/en-US/docs/DragDrop/Drag_Operations#dragstart">드롭하기</a>를 보시오.)</p> + </td> + </tr> + </tbody> +</table> + +<p class="note"><code>참고: dragstart</code>와 <code>dragend</code> 이벤트는 파일을 브라우저로 드래그할 때는 발생하지 않습니다.</p> + +<h2 id="인터페이스">인터페이스</h2> + +<p>HTML 드래그와 드롭 인터페이스는 {{domxref("DragEvent")}}, {{domxref("DataTransfer")}}, {{domxref("DataTransferItem")}}, {{domxref("DataTransferItemList")}} 입니다.</p> + +<p>{{domxref("DataTransfer")}} 객체는 드래그 형태나 드래그 데이터 (하나 이상의 아이템), 각 드래그 아이템의 종류 (MIME 종류) 와 같은 드래그 이벤트의 상태를 담고 있습니다. {{domxref("DataTransfer")}} 는 또한 드래그 데이터에 아이템을 추가하거나 제거하는 메소드를 가지고 있습니다. The {{domxref("DragEvent")}} 와 {{domxref("DataTransfer")}} 인터페이스만 있으면 어플리케이션에 HTML 드래그 앤 드롭 기능을 추가할 수 있습니다. 참고로 파이어폭스는 {{domxref("DataTransfer")}}에 {{anch("Gecko specific interfaces","Gecko-specific extensions")}} 와 같은 파이어폭스에서만 동작하는 추가적인 확장을 제공합니다. </p> + +<p>{{domxref("DataTransfer")}}는 {{domxref("DataTransferItem")}}의 {{domxref("DataTransferItemList","목록")}} 인 {{domxref("DataTransfer.items","items")}} 프로퍼티를 가지고 있습니다. 각 {{domxref("DataTransferItem")}} 는 하나의 드래그 아이템을 나타내고 각 아이템은 데이터의 종류 (<code>string</code> 혹은 <code>file</code>) 를 나타내는 {{domxref("DataTransferItem.kind","kind")}} 프로퍼티와 데이터 아이템의 종류 (MIME 종류) 를 나타내는 {{domxref("DataTransferItem.type","type")}} 프로퍼티를 가집니다. {{domxref("DataTransferItem")}}은 드래그 아이템의 데이터를 가져오는 메소드를 제공합니다.</p> + +<p>{{domxref("DataTransferItemList")}} 객체는 {{domxref("DataTransferItem")}}의 리스트입니다. 이 리스트 객체는 세 개의 메소드 - 드래그 아이템을 리스트에 추가하거나, 리스트에서 아이템을 삭제하거나, 모든 드래그 아이템을 리스트에서 삭제하는 메소드 - 를 가집니다.</p> + +<p>A key difference between the {{domxref("DataTransfer")}} and {{domxref("DataTransferItem")}} interfaces is that the former uses the synchronous {{domxref("DataTransfer.getData","getData()")}} method to access a drag item's data, whereas the later uses the asynchronous {{domxref("DataTransferItem.getAsString","getAsString()")}} method to access a drag item's data.</p> + +<p>{{domxref("DataTransfer")}}와 {{domxref("DataTransferItem")}}의 가장 중요한 차이점은 전자는 드래그 아이템의 데이터에 접근하기 위해 동기 메소드인 {{domxref("DataTransfer.getData","getData()")}}를 사용하는데 반해, 후자는 비동기 메소드인 {{domxref("DataTransferItem.getAsString","getAsString()")}}를 사용한다는 점입니다.</p> + +<p class="note">참고: {{domxref("DragEvent")}} and {{domxref("DataTransfer")}}는 여러 데스크탑 브라우저에서 폭넓게 지원하고 있습니다. 하지만 {{domxref("DataTransferItem")}}와 {{domxref("DataTransferItemList")}}는 제한적으로 사용 가능합니다. 드래그 앤 드롭의 상호 운용성에 대한 더 많은 정보를 찾아보기 위해 {{anch("Interoperability")}}를 보십시오.</p> + +<h3 id="Gecko_한정_인터페이스">Gecko 한정 인터페이스</h3> + +<p>모질라와 파이어폭스는 표준 드래그 앤 드롭 모델에서 제공하지 않는 몇가지 기능들을 추가로 제공합니다. 여러 개의 아이템을 동시에 드래그하거나 파일과 같이 문자열이 아닌 데이터를 드래그 하기 위한 여러 편리한 기능을 제공합니다. 더 많은 정보를 찾아보기 위해, <a href="/en-US/docs/DragDrop/Dragging_and_Dropping_Multiple_Items" title="Dragging and Dropping Multiple Items">Dragging and Dropping Multiple Items</a>을 보십시오. 덧붙여, 모든 Gecko 한정 프로퍼티나 Gecko 한정 메소드를 찾아보기 위해 {{domxref("DataTransfer")}} 참조 페이지도 보시기 바랍니다.</p> + +<h2 id="기본">기본</h2> + +<p>이번 절은 드래그 앤 드롭 기능을 추가하기 위한 기본적인 방법을 요약하고 있습니다. 각 절은 단계를 설명하고, 짧은 코드 예제와 추가적인 정보를 위한 링크를 포함합니다.</p> + +<h3 id="어떤_것이_draggable인지_확인하기">어떤 것이 <em>draggable</em>인지 확인하기</h3> + +<p>하나의 요소를 draggable로 만들기 위해서는 {{htmlattrxref("draggable")}}와 {{domxref("GlobalEventHandlers.ondragstart","ondragstart")}} 전역 이벤트 핸들러를 아래 예제 코드와 같이 추가해야합니다.</p> + +<pre class="brush: js notranslate">function dragstart_handler(ev) { + console.log("dragStart"); + // 데이터 전달 객체에 대상 요소의 id를 추가합니다. + ev.dataTransfer.setData("text/plain", ev.target.id); +} + +</pre> + +<pre class="notranslate"><script> + function dragstart_handler(ev) { + // 데이터 전달 객체에 대상 요소의 id를 추가합니다. + ev.dataTransfer.setData("text/plain", ev.target.id); + } + + window.addEventListener('DOMContentLoaded', () => { + // id를 통해 element를 가져옵니다. + const element = document.getElementById("p1"); + // 'dragstart' 이벤트 리스터를 추가합니다. + element.addEventListener("dragstart", dragstart_handler); + }); +</script> + +<p id="p1" draggable="true">This element is draggable.</p></pre> + +<p>추가 정보를 위해 <a href="/Web/HTML/Global_attributes/draggable" title="draggable global attribute">draggable attribute reference</a>와 <a href="/Web/Guide/HTML/Drag_operations#draggableattribute">Drag operations guide</a>를 참고하세요.</p> + +<h3 id="드래그_데이터_정의하기">드래그 데이터 정의하기</h3> + +<p>드래그할 때 자유롭게 데이터 아이템을 포함할 수 있습니다. 각 데이터 아이템은 특정 <code>type</code>의 {{domxref("DOMString","문자열")}}이며, 보통 <code>text/html</code>와 같은 MIME type입니다.</p> + +<p>각 {{domxref("DragEvent","drag event")}} 은 이벤트 데이터를 가지고 있는 {{domxref("DragEvent.dataTransfer","dataTransfer")}} 를 가집니다. 이 프로퍼티는 ({{domxref("DataTransfer")}} 객체) 드래그 데이터를 관리하는 메소드를 가집니다. {{domxref("DataTransfer.setData","setData()")}} 는 아래 코드 예제와 같이 아이템을 드래그 데이터에 추가할 때 사용합니다.</p> + +<pre class="brush: js notranslate">function dragstart_handler(ev) { + // 드래그 데이터를 추가합니다. + ev.dataTransfer.setData("text/plain", ev.target.id); + ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>"); + ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org"); +} +</pre> + +<p>드래그 앤 드롭에 사용할 수 있는 공통 데이터 타입 (텍스트, HTML, 링크, 파일 등) 의 목록을 보려면, <a href="/en-US/docs/DragDrop/Recommended_Drag_Types" title="Recommended Drag Types">Recommended Drag Types</a>를 참고하십시오. 드래그 데이터에 대한 추가적인 정보를 위해서는 <a href="/en-US/docs/Web/Guide/HTML/Drag_operations#dragdata" title="Drag Data">Drag Data</a>를 참고하십시오.</p> + +<h3 id="드래그_이미지_정의하기">드래그 이미지 정의하기</h3> + +<p>브라우저는 드래그 하는 동안 마우스 포인터 옆에 나타나는 이미지를 기본적으로 제공합니다. 어플리케이션에서 다른 이미지를 사용하기 원한다면 아래 예제와 같이 {{domxref("DataTransfer.setDragImage","setDragImage()")}}를 사용할 수 있습니다.</p> + +<pre class="brush: js notranslate">function dragstart_handler(ev) { + // 드래그 이미지로 사용할 이미지를 만듭니다. + // 참고: "example.gif"를 존재하는 이미지로 바꾸지 않으면 기본 드래그 이미지를 사용합니다. + var img = new Image(); + img.src = 'example.gif'; + ev.dataTransfer.setDragImage(img, 10, 10); +} +</pre> + +<p>드래그 이미지에 대해 더 알아보려면, <a href="/en-US/docs/DragDrop/Drag_Operations#dragfeedback" title="Setting the Drag Feedback Image">Setting the Drag Feedback Image</a>를 참고하세요.</p> + +<h3 id="드래그_효과_정의하기">드래그 효과 정의하기</h3> + +<p>{{domxref("DataTransfer.dropEffect","dropEffect")}} 프로퍼티는 드래그 앤 드롭 도중에 사용자에게 피드백 (보통 시각적인) 을 제공하기 위해 사용합니다. 브라우저가 드래그 하는 동안 어떤 마우스 포인터를 보여줄 지 결정합니다. 사용자가 마우스 포인터를 대상 드롭 요소에 올려놓으면, 브라우저는 드래그 효과에 적합한 마우스 포인터를 보여줄 것입니다.</p> + +<p>세 개의 효과가 정의되어 있습니다:</p> + +<p><code>copy</code>는 현재 위치에서 드롭하는 위치로 데이터가 복사될 것을 암시합니다.</p> + +<p><code>move</code>는 현재 위치에서 드롭하는 위치로 데이터가 이동할 것을 암시합니다.</p> + +<p><code>link</code>는 드래그하는 위치와 드롭하는 위치 간의 일종의 관계나 연결이 맺어진 다는 것을 암시합니다.</p> + +<p>특정 위치에서는 특정 효과가 허용된다는 것을 알려주기 위해 드래그 하는 도중에 효과가 변할 수 있습니다. 허용되는 경우에만 해당 위치에 드롭할 수 있습니다.</p> + +<p>다음 예제는 어떻게 이 프로퍼티를 사용하는지 보여줍니다.</p> + +<pre class="brush: js notranslate">function dragstart_handler(ev) { + // 드래그 효과를 copy로 지정합니다. + ev.dataTransfer.dropEffect = "copy"; +} +</pre> + +<p>더 자세한 설명은 <a href="/en-US/docs/Web/Guide/HTML/Drag_operations#drageffects" title="Drag Effects">Drag Effects</a>를 참고하세요.</p> + +<h3 id="드롭_지역_정의하기">드롭 지역 정의하기</h3> + +<p>기본적으로는 브라우저는 HTML 요소에 뭔가를 드롭했을 때 아무 일도 일어나지 않도록 합니다. 특정 요소가 드롭 지역 혹은 droppable로 만들기 위해서는 해당 요소가 {{domxref("GlobalEventHandlers.ondragover","ondragover")}}와 {{domxref("GlobalEventHandlers.ondrop","ondrop")}} 이벤트 핸들러 속성을 가져야합니다. 아래 예제는 두 요소를 어떻게 사용하고, 각 요소에 포함된 기본적인 이벤트 핸들러를 보여줍니다.</p> + +<pre class="notranslate"><script> +function dragover_handler(ev) { + ev.preventDefault(); + // dropEffect를 move로 설정. + ev.dataTransfer.dropEffect = "move"; +} +function drop_handler(ev) { + ev.preventDefault(); + // 대상의 id를 가져와 대상 DOM에 움직인 요소를 추가합니다. + const data = ev.dataTransfer.getData("text/plain"); + ev.target.appendChild(document.getElementById(data)); +} +</script> + +<p id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</p></pre> + +<p>각 핸들러는 {{domxref("Event.preventDefault","preventDefault()")}} 를 호출해 추가적인 이벤트 (터치 이벤트나 포인터 이벤트) 가 일어나지 않도록 합니다.</p> + +<p>추가적인 정보는, <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#droptargets">Specifying Drop Targets</a>를 참고하세요.</p> + +<h3 id="드롭_효과_다루기">드롭 효과 다루기</h3> + +<p>{{event("drop")}} 이벤트 핸들러는 자유롭게 드래그 데이터를 가공할 수 있습니다. 보통, 드래그 아이템과 각 아이템을 가공하기 위해 {{domxref("DataTransfer.getData","getData()")}}를 사용합니다. 추가로, {{domxref("DataTransfer.dropEffect","dropEffect")}} 값이나 보조키 상태에 따라 어플리케이션이 어떻게 동작할지를 결정할 수 있습니다.</p> + +<p>아래 예제는 드롭 핸들러가 드래그 데이터로부터 드래그하는 요소의 id를 가져와 드래그하는 요소를 드롭하는 요소로 옮기기위해 사용합니다.</p> + +<pre class="notranslate"><script> +function dragstart_handler(ev) { + // 데이터 전달 객체에 대상 요소의 id를 추가합니다. + ev.dataTransfer.setData("application/my-app", ev.target.id); + ev.dataTransfer.dropEffect = "move"; +} +function dragover_handler(ev) { + ev.preventDefault(); + ev.dataTransfer.dropEffect = "move" +} +function drop_handler(ev) { + ev.preventDefault(); + // 대상의 id를 가져와 이동한 대상 DOM 요소를 추가합니다. + // Get the id of the target and add the moved element to the target's DOM + const data = ev.dataTransfer.getData("application/my-app"); + ev.target.appendChild(document.getElementById(data)); +} +</script> + +<p id="p1" draggable="true" ondragstart="dragstart_handler(event)">This element is draggable.</p> +<div id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</div></pre> + +<p>더 많은 정보를 위해 <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#drop">Performing a Drop</a>을 보십시오.</p> + +<h3 id="드래그가_끝나면">드래그가 끝나면</h3> + +<p>드래그가 끝나면 드래그한 요소에 {{event("dragend")}} 이벤트가 발생합니다. 이 이벤트는 드래그가 완료되거나 중간에 취소되어도 발생합니다. {{event("dragend")}} 이벤트 핸들러는 {{domxref("DataTransfer.dropEffect","dropEffect")}} 프로퍼티를 확인해 드래그가 성공했는지를 확인할 수 있습니다.</p> + +<p>드래그 끝을 다루기 위한 더 많은 정보는 <a href="/en-US/docs/DragDrop/Drag_Operations#dragend" title="Finishing a Drag">Finishing a Drag</a>를 참고하세요. </p> + +<h2 id="상호_운용성">상호 운용성</h2> + +<p><a href="/docs/Web/API/DataTransferItem#Browser_compatibility">DataTransferItem interface's Browser Compatibility table</a>에 나온 대로, 드래그 앤 드롭은 상대적으로 여러 데스크톱 브라우저에서 폭넓게 사용할 수 있습니다 ({{domxref("DataTransferItem")}}는 {{domxref("DataTransferItemList")}} 덜 지원하지만). 또한 모바일 브라우저에서는 매우 한정적으로 사용할 수 있습니다.</p> + +<h2 id="Examples_and_demos" name="Examples_and_demos">예제와 데모</h2> + +<ul> + <li><a href="https://mdn.github.io/dom-examples/drag-and-drop/copy-move-DataTransfer.html">Copying and moving elements with the <code>DataTransfer</code> interface</a></li> + <li><a href="https://mdn.github.io/dom-examples/drag-and-drop/copy-move-DataTransferItemList.html">Copying and moving elements with the <code>DataTransferListItem</code> interface</a></li> + <li>파일 드래그 앤 드롭; 파이어폭스 전용: <a class="external" href="http://jsfiddle.net/9C2EF/" title="http://jsfiddle.net/9C2EF/">http://jsfiddle.net/9C2EF/</a></li> + <li>파일 드래그 앤 드롭; 모든 브라우저: <a class="external" href="https://jsbin.com/hiqasek/edit?html,js,output" title="https://jsbin.com/hiqasek">https://jsbin.com/hiqasek/</a></li> +</ul> + +<h2 id="명세서">명세서 </h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col"><strong>Specification</strong></th> + <th scope="col"><strong>Status</strong></th> + <th scope="col"><strong>Comment</strong></th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('HTML WHATWG', "#dnd")}}</td> + <td>{{Spec2('HTML WHATWG')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="See_also" name="See_also">더보기</h2> + +<ul> + <li><a class="internal" href="/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations" title="Drag Operations">Drag Operations</a></li> + <li><a class="internal" href="/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Multiple_items" title="Dragging and Dropping Multiple Items">Dragging and Dropping Multiple Items</a></li> + <li><a class="internal" href="/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types" title="Recommended Drag Types">Recommended Drag Types</a></li> + <li><a href="https://html.spec.whatwg.org/multipage/interaction.html#dnd" title="Drag and Drop Standard">HTML5 Living Standard: Drag and Drop</a></li> + <li><a href="http://caniuse.com/#search=draganddrop" title="Drag and Drop interoperability data from CanIUse">Drag and Drop interoperability data from CanIUse</a></li> +</ul> |