正如其他答案已经解释的那样,使用 DataTransfer.setData(format, data)
设置的 data
集合对于 dragenter
和 dragover
事件处理程序不可访问,而 format
可以在 DataTransfer.types
数组中访问。我们可以利用这一点将数据放入 format
中。
除了其他答案所述之外,我们不仅可以使用 format
存储单个属性,还可以存储实际的 JSON 对象。据我了解,format
将被转换为小写字母,我不确定特殊字符是否会导致任何问题,因此我将数据编码为十六进制字符串(更复杂的解决方案是使用 base32)。
const PREFIX = 'my-app-';
function setPublicDragData(dataTransfer, data) {
const json = JSON.stringify(data);
let encoded = '';
for (let i = 0; i < json.length; i++) {
encoded += json.charCodeAt(i).toString(16).padStart(2, '0');
}
dataTransfer.setData(`${PREFIX}${encoded}`, '');
}
function getPublicDragData(dataTransfer) {
for (const type of dataTransfer.types) {
if (type.startsWith(PREFIX)) {
const encoded = type.slice(PREFIX.length);
let json = '';
for (let i = 0; i < encoded.length; i += 2) {
json += String.fromCharCode(parseInt(encoded.slice(i, i + 2), 16));
}
return JSON.parse(json);
}
}
}
}
通过使用setPublicDragData(e.dataTransfer, data)
在dragstart
事件中设置数据,您可以实现在dragenter
/dragover
事件中使用getPublicDragData(e.dataTransfer)
检索数据。
除了使用全局变量或DOM元素的解决方案外,此解决方案还可用于从一个窗口拖动到另一个窗口。
请注意,根据您的用例,您可能需要向代码添加异常处理(以处理无效的JSON)。此外,我不知道大小限制是多少。
dragenter
/dragover
事件处理程序中,this
指向被拖动的元素,而不是正在拖动的元素。它等同于e.target
。例如:http://jsfiddle.net/TrevorBurnham/jWCSB/ - Trevor Burnham