Похоже, нет хорошего ответа на это.Во-первых, не все браузеры поддерживают одинаковую терминологию или функциональность DnD.Например, FireFox запускает событие dragenter
при выпадении, а Chrome, похоже, не обнаруживает событие drop
, когда объект находится в другом окне.
Вот мое тестирование до сих пор.Чтобы использовать, скопируйте содержимое в текстовый файл и сохраните как HTM или HTML.Затем откройте файл локально в вашем браузере.Откройте другое окно и откройте второй HTM.теперь у вас есть два окна, которые вы можете перетащить в и из.
wina-1.htm
<code><!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Window A</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.items {
position: relative;
}
.items > div {
margin-right: 5px;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
}
#log {
width: 100%;
height: 5em;
overflow-y: auto;
}
[draggable].idle {
background-color: rgba(255,0,0,0.75);
}
[draggable].selected {
background-color: rgba(255,0,0,0.95);
}
</style>
</head>
<body>
<pre id="log">
Тащите меня вокруг
Я не могу быть перемещен
var srcEl;функция log (s) {var now = new Date ();var t = now.getHours () + ":" + now.getMinutes () + ":" + now.getSeconds () + "."+ now.getMilliseconds ();var l = document.getElementById ("log");l.append (t + ":" + s + "\ r \ n");l.scrollTop = l.scrollHeight;} function dragStart (e) {log ("Начало перетаскивания:" + e.target.nodeName + "#" + e.target.id);srcEl = e.target;if (e.dataTransfer == undefined) {} else {e.dataTransfer.effectAllowed = "copyMove";log («Событие dataTransfer.effectAllowed:» + e.dataTransfer.effectAllowed);log ("Исходный элемент:" + srcEl.nodeName + "#" + srcEl.id);} this.classList.add ("selected");} function dragOver (e) {e.preventDefault ();log ("Перетаскивание:" + e.target.nodeName + (e.target.id! = ""? "#" + e.target.id: ""));вернуть ложь;} function dragLeave (e) {log ("Drag Leave:" + e.target.nodeName + (e.target.id! = ""? "#" + e.target.id: ""));} function dragStop (e) {log ("Drag End:" + e.target.nodeName + "#" + e.target.id);this.classList.remove ( "выбрано");} log ("Init");var item = document.getElementById ("draggable");item.addEventListener ('dragstart', dragStart, false);item.addEventListener ('dragover', dragOver, false);item.addEventListener ('dragleave', dragLeave, false);window.addEventListener ('dragleave', dragLeave, false);var items = document.querySelectorAll ('. items> div');[] .forEach.call (items, function (el) {el.addEventListener ('dragover', dragOver, false);});
Как вы видите, это использует сырой JavaScript.Я работал с пользовательским интерфейсом jQuery и сохранял таблицу стилей просто для удобства.У нас есть раздел для распечатки данных журнала, перетаскиваемого объекта и статического элемента.
winb-1.htm
<code><!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window B</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
.drag-item {
width: 100px;
height: 100px;
background-color: red;
}
body {
position: relative;
}
div.drag-helper {
width: 100px;
height: 100px;
background-color: red;
z-index: 1002;
position: relative;
}
#log {
width: 100%;
height: 5em;
line-height: 1em;
font-size: 1em;
overflow-y: auto;
}
#dropzone {
background-color: green;
width: 95%;
height: 340px;
}
</style>
</head>
<body>
<pre id="log">
jQuery (function ($) {function log (s) {var now = new Date (); var t = now.getHours () + ":" + now.getMinutes () + ":" +now.getSeconds () + "." + now.getMilliseconds (); $ ("# log"). append (t + ":" + s + "\ r \ n"). scrollTop ($ ("# log"..target) .attr ("id"). length? "#" + $ (e.target) .attr ("id"): ""));} function dragOver (e) {log ("Сработало перетаскивание через:"+ $ (e.target) .prop (" nodeName ") + ($ (e.target) .attr (" id "). length?" # "+ $ (e.target) .attr (" id "): "")); e.dataTransfer.dropEffect = 'move'; e.preventDefault ();} function handleDrop (e) {if (e.stopPropagation) {e.stopPropagation ();} log ("Drop Triggered:"+1$ (e.target) .attr ("id"). length? "#" + $ (e.target) .attr ("id"): ""));} log ("Init"); $ ("#dropzone "). on ({dragenter: dragEnter, dragover: dragOver, drop: handleDrop, mouseup: handleDrop, dragend: dragEnd});$ (window) .on ({dragenter: dragEnter, dragover: dragOver, drop: handleDrop, dragend: dragEnd});});
Окно B использует jQuery, поскольку предполагалось преобразовать элемент в jQuery UI Draggable.
Первое, что нужно знать, в пути нет пути. Поскольку элемент Source не является частью целевого DOM, это невозможно сделать. Его можно добавить и инициализировать как Draggable в событии drop
. По сути, то, что произойдет, будет создан новый элемент в то время, назначенные все данные.
Во-вторых, передача данных ненадежна, и я бы не использовал DataTransfer в качестве контейнера данных. Я бы посоветовал использовать localStorage. Это похоже на cookie и намного надежнее.
Например, я создал следующий объект данных:
{
id,
type,
attr: {
id,
class,
width,
height
},
content
}
Вот несколько примеров функций:
function collectData(obj){
return {
id: obj.attr("id"),
type: obj.prop("nodeName"),
attr: {
id: obj.attr("id"),
class: obj.attr("class"),
width: obj.width(),
height: obj.height()
},
content: obj.text().trim()
};
}
function saveData(k, d){
localStorage.setItem(k, JSON.stringify(d));
}
function getData(k){
return JSON.parse(localStorage.getItem(k));
}
function makeEl(d, pObj){
return $("<" + d.type +">", d.attr).html("<p>" + d.content + "</p>").appendTo(pObj);
}
$("#draggable").on('dragstart', function(e){
saveData("drag-data", collectData($(this)));
});
$("#dropzone").on('drop', function(e){
var item = makeEl(getData('drag-data'), $(this));
item.addClass("clone").position({
my: "center",
of: e
}).draggable();
});
Теоретически это должно работать. На практике я столкнулся с кучей препятствий. Я бы предложил что-то вроде действия типа «нажми и скопируй». Когда пользователь щелкает элемент в окне A (выбирая его), а затем щелкает, где он хочет, чтобы он находился в окне B. Снова используя localStorage, элемент может быть клонирован в новом месте.
Wina-3.htm
<code><!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.items {
position: relative;
}
.items > div {
margin-right: 5px;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
}
#log {
width: 100%;
height: 5em;
overflow-y: auto;
}
[draggable].idle {
background-color: rgba(255,0,0,0.5);
}
[draggable].selected {
background-color: rgba(255,0,0,0.95);
}
</style>
</head>
<body>
<pre id="log">
var intv;
журнал (ы) функций {
var now = new Date ();
var t = now.getHours () + ":" + now.getMinutes () + ":" + now.getSeconds () + "." + now.getMilliseconds ();
var l = document.getElementById ("log");
l.append (t + ":" + s + "\ r \ n");
l.scrollTop = l.scrollHeight;
}
function collectData (el) {
вернуть {
id: el.id,
тип: el.nodeName,
attr: {
id: el.id,
class: el.className,
ширина: эл. ширина,
высота: высота
},
содержание: el.innerText
};
}
функция saveData (k, v) {
localStorage.setItem (k, JSON.stringify (v));
}
function getData (k) {
return JSON.parse (localStorage.getItem (k));
}
function clearData (k) {
localStorage.setItem (k, null);
}
function selElem (e) {
var trg = e.target.nodeName + (e.target.id! = ""? "#" + e.target.id: "");
если (e.target.classList.contains ( "выбранные")) {
log ("Отменить выбор элемента:" + trg);
e.target.classList.remove ( "выбрано");
} еще {
log («Выбранный элемент:» + trg);
e.target.classList.add ( "выбрано");
saveData ("select-data", collectData (e.target));
}
intv = setInterval (function () {
if (getData ("select-data") == null) {
document.getElementsByClassName ( "выбрано") [0] .classList.remove ( "выбрано");
войти ( "невыбранный");
clearInterval (INTV);
}
}, 1000);
}
войти ( "INIT");
var item = document.getElementById ("draggable");
item.addEventListener ('click', selElem);
winb-3.htm
<code><!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window B</title>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
.drag-item {
width: 100px;
height: 100px;
background-color: red;
}
body {
position: relative;
}
#log {
width: 100%;
height: 5em;
line-height: 1em;
font-size: 1em;
overflow-y: auto;
}
#dropzone {
background-color: green;
width: 95%;
height: 340px;
position: relative;
}
.cloned {
position: absolute;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
background-color: rgba(255,0,0,0.75);
}
</style>
</head>
<body>
<pre id="log">
jQuery (функция ($) {
журнал (ы) функций {
var now = new Date ();
var t = now.getHours () + ":" + now.getMinutes () + ":" + now.getSeconds
() + "." + now.getMilliseconds ();
$ ("# log"). append (t + ":" + s + "\ r \ n"). scrollTop ($ ("# log"). prop
( "ScrollHeight"));
}
function getData (k) {
console.log ("Получение данных: '" + k + "'", localStorage.getItem (k));
return JSON.parse (localStorage.getItem (k));
}
function clearData (k) {
журнал («Очистить данные»);
localStorage.setItem (k, null);
}
function makeEl (dObj, pObj) {
console.log (dObj, pObj);
return $ ("<" + dObj.type + ">", dObj.attr) .html ("
" + dObj.content +
"
") appendTo (PObj).
}
function handleDrop (e) {
if (e.stopPropagation) {
e.stopPropagation ();
}
var trg = $ (e.target);
log ("Drop Triggered:" + trg.prop ("nodeName") + "#" + trg.attr ("id"));
var d, item;
if (e.target.id == "dropzone" && (e.type == "click" || e.type ==
"MouseUp")) {
журнал («Обнаружен клик - сбор данных»);
d = getData ("select-data");
console.log («Данные», д);d.attr.id = "clone-" + ($ ("# dropzone .cloned"). length + 1);log ("Создание элемента:" + d.type + "#" + d.attr.id);item = makeEl (d, trg);item.removeClass ("selected"). addClass ("cloned"). position ({my: "center", of: e}). draggable ();clearData ( "Select-данные");вернуть истину;} вернуть ложь;} log ("Init");$ ("# dropzone"). on ({mouseup: handleDrop, click: handleDrop});});
Я знаю, что это не тот ответ, который вы ищете, и для этого вам нужно попытаться задать реальный вопрос.Вы, кажется, продолжаете задавать вопросы.
Надеюсь, это поможет.