JavaScript. Подробное руководство, 6-е издание, стр. 267

<b>    // Этот обработчик вызывается, когда буксируемый объект выходит за границы списка</b>

<b>    // или за границы одного из его дочерних элементов. Если объект действительно</b>

<b>    // покидает границы списка (а не границы одного из его элементов),</b>

<b>    // то нужно снять подсветку списка,</b>

<b>    list.ondragleave = function(e) {</b>

<b>      е = е || window.event;</b>

<b>      var to = e.relatedTarget;</b>

<b>      // Если буксируемый объект покидает границы списка или если количество выходов</b>

<b>      // за границы совпадает с количеством входов, следует снять подсветку списка entered--;</b>

<b>      if ((to &amp;&amp; !ischild(to,list)) || entered &lt;= 0) {</b>

<b>        list.className = original_class;</b>

<b>        entered = 0;</b>

<b>      }</b>

<b>      return false;</b>

<b>    }</b>

<b>    // Этот обработчик вызывается, когда происходит сброс объекта.</b>

<b>    // Он извлекает сброшенный текст и превращает его в новый элемент &lt;li&gt;</b>

<b>    list.ondrop = function(e) {</b>

<b>      е = е И window.event; // Получить объект события</b>

<b>      // Получить сброшенные данные в текстовом формате.</b>

<b>      // &quot;Text&quot; - это псевдоним для &quot;text/plain&quot;.</b>

<b>      // IE не поддерживает &quot;text/plain”, поэтому здесь используется &quot;Text&quot;.</b>

<b>      var dt = e.dataTransfer; // объект dataTransfer</b>

<b>      var text = dt.getData(&quot;Text&quot;); // Получить данные в текстовом формате.</b>

<b>      // Если был получен некоторый текст, превратить его в новый элемент</b>

<b>      // списка и добавить в конец,</b>

<b>      if (text) {</b>

<b>        var item = document.createElement(&quot;li&quot;); // Создать новый &lt;li&gt;</b>

<b>        item.draggable = true; // Сделать буксируемым</b>

<b>        item.appendChild(document.createTextNode(text)); // Добавить текст</b>

<b>        list.appendChild(item); // Добавить в список</b>

<b>        // Восстановить первоначальный стиль списка и сбросить счетчик entered</b>

<b>        list.className = original_class;</b>

<b>        entered = 0;</b>

<b>        return false;</b>

<b>      }</b>

<b>    };</b>

<b>    // Сделать все элементы списка буксируемыми</b>

<b>    var items = list.getElementsByTagName(&quot;li&quot;);</b>

<b>    for(var і = 0; і &lt; items.length; i++) items[i].draggable = true;</b>

<b>    // И зарегистрировать обработчики для поддержки буксировки элементов списка.</b>

<b>    // Обратите внимание, что мы поместили эти обработчики в список и ожидаем,</b>

<b>    // что события будут всплывать вверх от элементов списка.</b>

<b>    // Этот обработчик вызывается, когда буксировка начинается внутри списка,</b>

<b>    list.ondragstart = function(e) {</b>

<b>      var е = е || window.event;</b>

<b>      var target = e.target || e.srcElement;</b>

<b>      // Если всплыло событие от элемента, отличного от &lt;li&gt;, игнорировать его</b>

<b>      if (target.tagName !== &quot;li&quot;) return false;</b>

<b>      // Получить важный объект dataTransfer</b>

<b>      var dt = e.dataTransfer;</b>

<b>      // Сохранить данные и указать информацию об их формате</b>

<b>      dt.setData(&quot;Text&quot;, target.innerText || target.textContent);</b>

<b>      // Сообщить, что поддерживаются операции копирования и перемещения</b>

<b>      dt.effectAllowed = &quot;copyMove&quot;;</b>

<b>    };</b>

<b>    // Этот обработчик вызывается после успешного сброса</b>

<b>    list.ondragend = function(e) {</b>

<b>      е = е || window.event;</b>

<b>      var target = e.target || e.srcElement;</b>

<b>      // Если выполнялась операция перемещения, удалить элемент списка.</b>

<b>      // В IE8 это свойство будет иметь значение &quot;none&quot;, если явно</b>