Это 4-й день моего участия в августовском испытании обновлений.Подробности о событии:Испытание августовского обновления
событие перетаскивания
Типы событий перетаскивания
Перетаскивание — это когда пользователь, удерживая кнопку мыши на объекте, перетаскивает его в другое место, а затем отпускает кнопку мыши, чтобы поместить туда объект.
Существует несколько типов перетаскиваемых объектов, включая узлы элементов, изображения, ссылки, выделенный текст и т. д. На веб-страницах, за исключением узлов элементов, которые нельзя перетаскивать по умолчанию, другие (изображения, ссылки, выделенный текст) можно перетаскивать напрямую. Чтобы сделать узел элемента перетаскиваемым, узелdraggable
свойство установлено наtrue
.
<div draggable="true">
此区域可拖拉
</div>
код вышеdiv
Блоки можно перетаскивать прямо с помощью мыши на веб-странице. Когда вы отпускаете кнопку мыши, эффект перетаскивания исчезает, и блок остается в исходном положении.
draggable
атрибуты могут использоваться на любом узле элемента, но изображения (<img>
) и ссылки (<a>
) без этого атрибута можно перетаскивать. Для них при использовании этого свойства часто устанавливается значениеfalse
, предотвращая перетаскивание обоих элементов.
Обратите внимание, что как только узел элементаdraggable
свойство установлено наtrue
, вы больше не можете использовать мышь для выбора текста или дочерних узлов внутри узла.
При перетаскивании узла элемента или выделенного текста постоянно запускаются события перетаскивания, включая некоторые из следующих событий.
-
drag
: во время процесса перетаскивания непрерывно запускать перетаскиваемый узел (с интервалом в несколько сотен миллисекунд). -
dragstart
: Запускается на перетаскиваемом узле, когда пользователь начинает перетаскивание, событиеtarget
Атрибут — это перетаскиваемый узел. Обычно перетаскиваемые данные должны быть указаны в функции слушателя этого события. -
dragend
: Запускается на перетаскиваемом узле, когда перетаскивание закончилось (отпустите кнопку мыши или нажмите клавишу ESC), событиеtarget
Атрибут — это перетаскиваемый узел. это сdragstart
событие, запущенное на том же узле. Независимо от того, происходит ли перетаскивание по окнам или оно прерывается на полпути,dragend
События всегда срабатывают. -
dragenter
: при перетаскивании в текущий узел срабатывает один раз на текущем узле, и событиеtarget
Свойство является текущим узлом. Обычно в функции слушателя этого события указывают, разрешать ли перетаскиваемые данные сбрасывать (сбрасывать) на текущем узле. Если текущий узел не имеет функции прослушивания события или функция прослушивателя не выполняет никаких операций, это означает, что данные не могут быть удалены на текущем узле. В функции прослушивателя этого события также задается визуальное отображение перетаскивания в текущий узел. -
dragover
: при перетаскивании на текущий узел он будет продолжать срабатывать на текущем узле (с разницей в несколько сотен миллисекунд), а событиеtarget
Свойство является текущим узлом. Это событие связано сdragenter
Разница между событиями в том,dragenter
Событие срабатывает при входе в узел, затем, пока узел не вышел,dragover
События будут продолжаться. -
dragleave
: Запускается на текущем узле, когда операция перетаскивания выходит за пределы текущего узла, событиеtarget
Свойство является текущим узлом. Если вы хотите визуально отобразить текущий узел операции перетаскивания, установите его в функции прослушивателя этого события. -
drop
: Запускается на целевом узле, когда перетаскиваемый узел или выделенный текст передаются на целевой узел. Обратите внимание, что если текущий узел не позволяетdrop
, событие не сработает, даже если кнопка мыши будет отпущена над узлом. Если пользователь нажмет клавишу ESC для отмены операции, событие не будет запущено. Функция прослушивания этого события отвечает за выборку данных перетаскивания и выполнение соответствующей обработки.
В следующем примере показано, как динамически изменить цвет фона перетаскиваемого узла.
div.addEventListener('dragstart', function (e) {
this.style.backgroundColor = 'red';
}, false);
div.addEventListener('dragend', function (e) {
this.style.backgroundColor = 'green';
}, false);
В приведенном выше кодеdiv
Когда узел перетаскивается, цвет фона меняется на красный, а когда перетаскивание заканчивается, он снова становится зеленым.
Ниже приведен пример, показывающий, как перетащить узел из текущего родительского узла в другой родительский узел.
/* HTML 代码如下
<div class="dropzone">
<div id="draggable" draggable="true">
该节点可拖拉
</div>
</div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
*/
// 被拖拉节点
var dragged;
document.addEventListener('dragstart', function (event) {
// 保存被拖拉节点
dragged = event.target;
// 被拖拉节点的背景色变透明
event.target.style.opacity = 0.5;
}, false);
document.addEventListener('dragend', function (event) {
// 被拖拉节点的背景色恢复正常
event.target.style.opacity = '';
}, false);
document.addEventListener('dragover', function (event) {
// 防止拖拉效果被重置,允许被拖拉的节点放入目标节点
event.preventDefault();
}, false);
document.addEventListener('dragenter', function (event) {
// 目标节点的背景色变紫色
// 由于该事件会冒泡,所以要过滤节点
if (event.target.className === 'dropzone') {
event.target.style.background = 'purple';
}
}, false);
document.addEventListener('dragleave', function( event ) {
// 目标节点的背景色恢复原样
if (event.target.className === 'dropzone') {
event.target.style.background = '';
}
}, false);
document.addEventListener('drop', function( event ) {
// 防止事件默认行为(比如某些元素节点上可以打开链接),
event.preventDefault();
if (event.target.className === 'dropzone') {
// 恢复目标节点背景色
event.target.style.background = '';
// 将被拖拉节点插入目标节点
dragged.parentNode.removeChild(dragged);
event.target.appendChild( dragged );
}
}, false);
Есть несколько моментов, на которые следует обратить внимание в отношении событий перетаскивания.
- Процесс перетаскивания запускает только указанные выше события перетаскивания, хотя мышь движется, события мыши не будут запускаться.
- Перетащите файл из ОС в браузер, не срабатывает
dragstart
а такжеdragend
мероприятие. -
dragenter
а такжеdragover
Функция прослушивателя событий используется для извлечения перетаскиваемых данных (то есть для того, чтобы перетаскиваемый элемент мог быть удален). Поскольку большинство областей веб-страницы не подходят в качестве целевых узлов для перетаскивания элементов, настройки по умолчанию для этих двух событий таковы, что текущему узлу не разрешено принимать перетаскиваемые элементы. Если вы хотите удалить данные на целевом узле, вы должны сначала предотвратить поведение этих двух событий по умолчанию.
<div ondragover="return false">
<div ondragover="event.preventDefault()">
В приведенном выше коде без отмены события перетаскивания или предотвращения поведения по умолчанию вы не можетеdiv
Поместите перетащенный узел на узел.
Интерфейс DragEvent
События перетаскивания наследуютсяDragEvent
интерфейс, который наследуется отMouseEvent
интерфейс иEvent
интерфейс.
Браузер изначально предоставляетDragEvent()
Конструктор, используемый для создания экземпляра объекта события перетаскивания.
new DragEvent(type, options)
DragEvent()
Конструктор принимает два параметра, первый параметр — это строка, указывающая тип события, которое требуется, второй параметр — объект конфигурации события, который используется для установки свойств события, и этот параметр необязательный. объект конфигурации в дополнение к принятиюMouseEvent
интерфейс иEvent
Свойства конфигурации интерфейса также могут быть установленыdataTransfer
собственность либоnull
, либоDataTransfer
Экземпляр интерфейса.
DataTransfer
Объект экземпляра используется для чтения и записи данных, передаваемых в событии перетаскивания.Подробности см. в разделе «Интерфейс передачи данных» ниже.
Обзор интерфейса DataTransfer
Все экземпляры событий перетаскивания имеютDragEvent.dataTransfer
Атрибуты используются для чтения и записи данных, которые необходимо передать. Значение этого свойства равноDataTransfer
Экземпляр интерфейса.
Браузер изначально предоставляетDataTransfer()
конструктор для генерацииDataTransfer
объект экземпляра.
var dataTrans = new DataTransfer();
DataTransfer()
Конструктор не принимает никаких параметров.
Перетаскиваемые данные делятся на два аспекта: тип данных (он же формат) и значение данных. Тип данных — это строка MIME (например,text/plain
,image/jpeg
), значение данных представляет собой строку. Вообще говоря, если вы перетаскиваете фрагмент текста, данные по умолчанию соответствуют этому тексту; если вы перетаскиваете ссылку, данные по умолчанию соответствуют URL-адресу ссылки.
Когда начинается событие перетаскивания, разработчик может указать тип данных и значение данных. В процессе перетаскивания проявитель проходитdragenter
а такжеdragover
Функция прослушивателя событий, которая проверяет тип данных, чтобы определить, разрешено ли отбрасывать перетаскиваемый объект. Например, в области, где разрешено отбрасывать только ссылки, проверьте, соответствует ли перетаскиваемый тип данныхtext/uri-list
.
происходитьdrop
Когда происходит событие, функция слушателя извлекает перетаскиваемые данные и обрабатывает их.
Свойства экземпляра DataTransfer
DataTransfer.dropEffect
DataTransfer.dropEffect
Свойство используется для установки эффекта отбрасывания перетаскиваемого узла, который влияет на форму мыши при перетаскивании по соответствующей области. Может принимать следующие значения.
- копировать: скопировать перетаскиваемый узел
- move: переместить перетащенный узел
- ссылка: создать ссылку на перетаскиваемый узел
- none: нельзя удалить перетаскиваемый узел
Помимо указанных выше значений, установка других значений недействительна.
target.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = 'copy';
});
В приведенном выше коде, как только перетаскиваемый элементdrop
, принятый регион реплицирует узел.
dropEffect
свойства, как правило, вdragenter
а такжеdragover
Установите в функции слушателя событий, дляdragstart
,drag
,dragleave
Для этих трех событий это свойство не действует. Поскольку это свойство действительно только для области, которая принимает перетаскиваемый узел, оно не влияет на сам перетаскиваемый узел. После входа в целевую область поведение перетаскивания будет инициализировано для заданного эффекта.
DataTransfer.effectAllowed
DataTransfer.effectAllowed
Свойство устанавливает эффекты, разрешенные в этом перетаскивании. Может принимать следующие значения.
- копировать: скопировать перетаскиваемый узел
- move: переместить перетащенный узел
- ссылка: создать ссылку на перетаскиваемый узел
- копироватьСсылка: разрешить
copy
илиlink
- copyMove: разрешить
copy
илиmove
- ссылкаПереместить: разрешить
link
илиmove
- все: разрешить все эффекты
- none: нельзя удалить перетаскиваемый узел
- неинициализированный: значение по умолчанию, эквивалентное
all
Если эффект не разрешен, пользователь не может добиться этого эффекта в целевом узле.
Это свойство связано сdropEffect
Свойства — это две стороны одного и того же. Первый устанавливает эффект, разрешенный перетаскиваемым узлом, а второй устанавливает эффект области, которая принимает перетаскивание, и они часто используются вместе.
dragstart
Для установки этого свойства можно использовать функцию прослушивателя событий. Установка этого свойства в функции прослушивателя других событий недопустима.
source.addEventListener('dragstart', function (e) {
e.dataTransfer.effectAllowed = 'move';
});
target.addEventListener('dragover', function (e) {
e.dataTransfer.dropEffect = 'move';
});
если толькоdropEffect
свойства иeffectAllowed
Среди свойств естьnone
, это невозможно сделать на целевом узлеdrop
работать.
DataTransfer.files
DataTransfer.files
Свойство представляет собой объект FileList, содержащий набор локальных файлов, которые можно использовать для передачи в операции перетаскивания. Если это перетаскивание не затрагивает файлы, это свойство является пустым объектом FileList.
Ниже приведен пример получения перетаскиваемого файла.
// HTML 代码如下
// <div id="output" style="min-height: 200px;border: 1px solid black;">
// 文件拖拉到这里
// </div>
var div = document.getElementById('output');
div.addEventListener("dragenter", function( event ) {
div.textContent = '';
event.stopPropagation();
event.preventDefault();
}, false);
div.addEventListener("dragover", function( event ) {
event.stopPropagation();
event.preventDefault();
}, false);
div.addEventListener("drop", function( event ) {
event.stopPropagation();
event.preventDefault();
var files = event.dataTransfer.files;
for (var i = 0; i < files.length; i++) {
div.textContent += files[i].name + ' ' + files[i].size + '字节\n';
}
}, false);
В приведенном выше коде с помощьюdataTransfer.files
Свойства для чтения информации о перетаскиваемом файле. Если вы хотите прочитать содержимое файла, вам нужно использоватьFileReader
объект.
div.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
var fileList = e.dataTransfer.files;
if (fileList.length > 0) {
var file = fileList[0];
var reader = new FileReader();
reader.onloadend = function(e) {
if (e.target.readyState === FileReader.DONE) {
var content = reader.result;
div.innerHTML = 'File: ' + file.name + '\n\n' + content;
}
}
reader.readAsBinaryString(file);
}
});
DataTransfer.types
DataTransfer.types
Свойство представляет собой массив только для чтения, где каждый элемент представляет собой строку, содержащую перетаскиваемый формат данных (обычно значение MIME). Например, если перетаскивание представляет собой текст, соответствующий элементtext/plain
.
Вот пример, проверивdataTransfer
Тип атрибута, который определяет, разрешить ли выполнение на текущем узлеdrop
работать.
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();
}
В приведенном выше коде только в том случае, если один из перетаскиваемых узлов является ссылкой, он может перетаскиваться на текущий узел.
DataTransfer.items
DataTransfer.items
Свойство возвращает подобный массиву объект только для чтения (экземпляр DataTransferItemList), каждый член которого является объектом (экземпляром DataTransferItem) для этого перетаскивания. Если текущее перетаскивание не содержит объектов, возвращается пустой объект.
Экземпляр DataTransferItemList имеет следующие свойства и методы.
-
length
: Возвращает количество участников -
add(data, type)
: добавить указанный контент и тип (например,text/html
а такжеtext/plain
) строка как элемент -
add(file)
:add
Другое использование метода, добавление файла в качестве члена -
remove(index)
: удалить член в указанной позиции -
clear()
: удалить всех членов
Экземпляры DataTransferItem имеют следующие свойства и методы.
-
kind
: возвращает тип члена (string
ещеfile
). -
type
: возвращает тип члена (обычно значение MIME). -
getAsFile()
: Если перетаскиваемый файл, вернуть файл, в противном случае вернутьnull
. -
getAsString(callback)
: если перетаскиваемая строка является строкой, передайте символ указанной функции обратного вызова для обработки. Этот метод является асинхронным, поэтому необходимо передать функцию обратного вызова.
Ниже приведен пример.
div.addEventListener('drop', function (e) {
e.preventDefault();
if (e.dataTransfer.items != null) {
for (var i = 0; i < e.dataTransfer.items.length; i++) {
console.log(e.dataTransfer.items[i].kind + ': ' + e.dataTransfer.items[i].type);
}
}
});
Экземплярные методы передачи данных
DataTransfer.setData()
DataTransfer.setData()
Этот метод используется для установки данных, переносимых событием перетаскивания. Этот метод не имеет возвращаемого значения.
event.dataTransfer.setData('text/plain', 'Text to drag');
Приведенный выше код добавляет простые текстовые данные для текущего события перетаскивания.
Этот метод принимает два параметра, оба из которых являются строками. Первый параметр представляет тип данных (например,text/plain
), второй параметр — это конкретные данные. Если указанный тип данных находится вdataTransfer
Если атрибут не существует, данные будут добавлены, в противном случае исходные данные будут заменены новыми данными.
Если текстовое поле перетаскивается или выделенный текст перетаскивается, соответствующие текстовые данные будут добавлены кdataTransfer
свойства, не нужно задавать вручную.
<div draggable="true">
aaa
</div>
В приведенном выше коде перетащите это<div>
Элементы автоматически несут текстовые данныеaaa
.
использоватьsetData
метод замены исходных данных.
<div
draggable="true"
ondragstart="event.dataTransfer.setData('text/plain', 'bbb')"
>
aaa
</div>
В приведенном выше коде данные перетаскивания на самом делеbbb
, вместоaaa
.
Ниже добавлены другие типы данных. из-заtext/plain
Это наиболее часто поддерживаемый формат.Для обеспечения совместимости рекомендуется всегда сохранять данные в текстовом формате в конце.
var dt = event.dataTransfer;
// 添加链接
dt.setData('text/uri-list', 'http://www.example.com');
dt.setData('text/plain', 'http://www.example.com');
// 添加 HTML 代码
dt.setData('text/html', 'Hello there, <strong>stranger</strong>');
dt.setData('text/plain', 'Hello there, <strong>stranger</strong>');
// 添加图像的 URL
dt.setData('text/uri-list', imageurl);
dt.setData('text/plain', imageurl);
Данные могут предоставляться сразу в нескольких форматах.
var dt = event.dataTransfer;
dt.setData('application/x-bookmark', bookmarkString);
dt.setData('text/uri-list', 'http://www.example.com');
dt.setData('text/plain', 'http://www.example.com');
В приведенном выше коде при сохранении трех типов данных об одном и том же событии событие перетаскивания может относиться к разным объектам.drop
разные значения. Обратите внимание, что первый формат является настраиваемым форматом, который не может быть прочитан браузерами по умолчанию, а это означает, что только узел с развернутым определенным кодом можноdrop
(читать) эти данные.
DataTransfer.getData()
DataTransfer.getData()
Метод принимает строку (представляющую тип данных) в качестве параметра и возвращает данные указанного типа (обычно используется с событием).setData
добавлен метод). Возвращает пустую строку, если данные указанного типа не существуют. обычно толькоdrop
После запуска события данные могут быть получены.
Ниже приведенdrop
Функция прослушивателя событий используется для получения данных указанного типа.
function onDrop(event) {
var data = event.dataTransfer.getData('text/plain');
event.target.textContent = data;
event.preventDefault();
}
Приведенный выше код извлекает текстовые данные события перетаскивания и заменяет их текстовым содержимым текущего узла. Обратите внимание, что поведение браузера по умолчанию также должно быть отменено в это время, потому что, если пользователь перетащит ссылку, браузер по умолчанию откроет ссылку в текущем окне.
getData
Метод возвращает строку, которую необходимо проанализировать вручную, если она содержит несколько фрагментов данных.
function doDrop(event) {
var lines = event.dataTransfer.getData('text/uri-list').split('\n');
for (let line of lines) {
let link = document.createElement('a');
link.href = line;
link.textContent = line;
event.target.appendChild(link);
}
event.preventDefault();
}
В приведенном выше кодеgetData
Метод возвращает набор ссылок, которые должны быть разрешены сами по себе.
Значение типа указывается какURL
, вы можете удалить первую действующую ссылку.
var link = event.dataTransfer.getData('URL');
В следующем примере показано извлечение данных из различных типов данных.
function doDrop(event) {
var types = event.dataTransfer.types;
var supportedTypes = ['text/uri-list', 'text/plain'];
types = supportedTypes.filter(function (value) { types.includes(value) });
if (types.length) {
var data = event.dataTransfer.getData(types[0]);
}
event.preventDefault();
}
DataTransfer.clearData()
DataTransfer.clearData()
Метод принимает строку (указанный тип данных) в качестве параметра, удаляет данные указанного типа, принадлежащего события. Если вы не укажете тип, удалите все данные. Если указанный тип не существует, вызывая метод не дает никакого эффекта.
event.dataTransfer.clearData('text/uri-list');
Приведенный выше код очищает событиеtext/uri-list
тип данных.
Этот метод не удаляет перетаскиваемый файл, поэтому после вызова этого методаDataTransfer.types
свойства могут все еще возвращатьсяFiles
Тип (при условии, что есть перетаскивание файла).
Обратите внимание, что этот метод можно использовать только вdragstart
Он используется в функции прослушивателя событий, потому что это единственный момент, когда данные операции перетаскивания могут быть записаны.
DataTransfer.setDragImage()
Во время перетаскивания (dragstart
После запуска события браузер отобразит изображение, которое перемещается с помощью мыши, представляющее перетаскиваемый узел. Это изображение создается автоматически, обычно показывая внешний вид перетаскиваемого узла, нет необходимости настраивать его самостоятельно.
DataTransfer.setDragImage()
способ настроить это изображение. Он принимает три параметра. первый<img>
узел или<canvas>
узел, если он опущен или какnull
, используется внешний вид перетаскиваемого узла, второй и третий параметры - абсцисса и ордината мыши относительно левого верхнего угла картинки.
Ниже приведен пример.
/* HTML 代码如下
<div id="drag-with-image" class="dragdemo" draggable="true">
drag me
</div>
*/
var div = document.getElementById('drag-with-image');
div.addEventListener('dragstart', function (e) {
var img = document.createElement('img');
img.src = 'http://path/to/img';
e.dataTransfer.setDragImage(img, 0, 0);
}, false);