JavaScript. Подробное руководство, 6-е издание, стр. 264
• Они должны взаимодействовать с операционной системой, чтобы обеспечить возможность взаимодействий между различными приложениями.
• Они должны поддерживать такие операции передачи данных, как «перемещение», «копирование» и «создание ссылки», позволять источникам и приемникам ограничивать множество допустимых операций, а также давать пользователям возможность выбирать (обычно с помощью клавиш-модификаторов) операцию из разрешенного набора.
• Они должны предоставлять источнику способ определять ярлык или изображение, которое будет отображаться в процессе буксировки.
• Они должны предоставлять механизм событий для посылки извещений источнику и приемнику в процессе буксировки.
Корпорация Microsoft реализовала прикладной интерфейс механизма буксировки в ранних версиях IE. Он был не очень хорошо продуман и плохо документирован, тем не менее другие производители броузеров попытались скопировать его, а спецификация HTML5 стандартизовала некоторый API, напоминающий прикладной интерфейс в IE, и добавила новые особенности, делающие этот API более простым в использовании. На момент написания этих строк данный новый, более простой в использовании API буксировки еще не был реализован, поэтому в этом разделе будет рассматриваться прикладной интерфейс в IE, как взятый за основу стандартом HTML5.
Прикладной интерфейс механизма буксировки в IE довольно сложен в использовании, а различия между реализациями в текущих броузерах не позволяют использовать наиболее сложные части API переносимым способом. Тем не менее он дает возможность веб-приложениям участвовать в операциях буксировки подобно обычным приложениям. Броузеры всегда позволяли выполнять простейшие операции буксировки. Если выделить текст в веб-броузере, его легко можно отбуксировать в текстовый процессор. А если выделить URL-адрес в текстовом процессоре, его можно отбуксировать в броузер, чтобы открыть страницу с этим адресом. В этом разделе будет показано, как создавать собственные источники, которые позволят перемещать данные, не являющиеся текстом, и собственные приемники, откликающиеся на попытки оставить в них данные некоторым способом, помимо простого их отображения.
Механизм буксировки всегда опирался на события, поэтому в JavaScript API реализовано два множества событий: события из первого множества возбуждаются в источнике данных, а из второго - в приемнике. Все обработчики событий буксировки получают объект события, подобный объекту события мыши, с дополнительным свойством
<b>dataTransfer</b><b>DataTransfer</b>События, возбуждаемые в источнике, относительно просты, поэтому начнем с них. Источником для механизма буксировки является любой элемент документа, имеющий HTML-атрибут
<b>draggable</b><b>dataTransfer.setData(),</b><b>dataTransfer.items.add()</b><b>dataTransfer.effectAllowed</b><b>dataTransfer.setDragImage()</b><b>dataTransfer.addElement()</b>В процессе буксировки броузер возбуждает в источнике данных события «drag». Обработчик этого события можно использовать для изменения перемещаемого ярлыка или перемещаемых данных, но в общем случае нет никакой необходимости регистрировать обработчики событий «drag».
Когда выполняется сброс, возбуждается событие «dragend». Если источник поддерживает операцию «перемещения», он должен проверить свойство
<b>dataTransfer.dropEffect</b>Событие «dragstart» является единственным, обработку которого необходимо реализовать в простейшем источнике данных. Реализация такого источника представлена в примере 17.4. Он отображает текущее время в формате «hh:mm» в элементе <span> и обновляет время раз в минуту. Если бы это было все, что реализует пример, пользователь мог бы просто выделить отображаемый текст и от; буксировать его. Но этот пример превращает часы в источник данных для механизма буксировки, устанавливая свойство
<b>draggable</b><b>ondragstart</b><b>dataTransfer.setData()</b><b>dataTransfer.setDragIcon(),</b>Пример 17.4. Источник данных для механизма буксировки
<b><script src="whenReady.js"></script></b><b><script></b><b> whenReady(function() {</b><b> var clock = document.getElementById("clock"); // Элемент часов</b><b> var icon = new Image(); // Буксируемое изображение</b><b> icon.src = "clock-icon.png"; // URL-адрес изображения</b><b> // Отображает время раз в минуту </b><b> function displayTime() {</b><b> var now = new Date(); // Получить текущее время</b><b> var hrs = now.getHours(), mins = now.getMinutes();</b><b> if (mins < 10) mins = "0" + mins;</b><b> clock.innerHTML = hrs + ":" + mins; // Отобразить текущее время</b><b> setTimeout(displayTime, 60000); // Запустить через 1 минуту</b><b> }</b><b> displayTime();</b>