Почему перетаскивание данных в HTML-объект перетаскивания становится объектом внутри iframe - PullRequest
0 голосов
/ 04 июня 2019

Я тестирую некоторый код для веб-разработчика. Используя DnD API, я хочу иметь возможность перетаскивать элемент в iframe. Однако при отбрасывании элемента, используя e.target.appendChild(), я получаю сообщение об ошибке, говорящее, что предоставленный параметр не является Элементом. Используя e.target.append(), он падает [object HTMLDivElement].

Это всего лишь простой тестовый код, потому что я мало работал с API. Но я пробовал StackOverflow, Google, изучал API и читал сообщения в блогах. Ничего не работает Изначально я установил window.ondrop и другие события в скрипте, загруженном внутри iframe, но столкнулся с ошибкой, поэтому я переместил все в один скрипт и снова установил события, используя document.querySelector('iframe').contentDocument.ondrop. Все события, кроме dragstart, основаны внутри iframe.

const element = document.querySelector('.draggable');
const iframe = document.querySelector('iframe');
const iframeBody = iframe.contentDocument.querySelector('body');

element.ondragstart = e => {
  console.log('mainWindow: dragstart');
  element.id = 'draggable';
  e.dataTransfer.setData('text/html', e.target);
  console.log(element);
  console.log(e.dataTransfer.getData('text/html'));

  e.dataTransfer.dropEffect = 'copy';
};

iframe.contentWindow.ondragenter = e => {
  e.preventDefault();
  iframeBody.style.transition = '0.5s';
  iframeBody.style.opacity = 0.5;
  e.dataTransfer.dropEffect = 'copy';
  console.log('contentWindow: dragenter');
  console.log(e.dataTransfer.getData('text/html'));
};

iframe.contentWindow.ondragover = e => {
  e.preventDefault();
  console.log(e.dataTransfer.getData('text/html'));
};

iframe.contentWindow.ondrop = e => {
  e.preventDefault();
  console.log('contentWindow: drop');
  const data = e.dataTransfer.getData('text/html');
  console.log(e.dataTransfer.getData('text/html'));

  e.target.appendChild(data);
};

iframe.contentWindow.ondragleave = e => {
  iframeBody.style.opacity = 1;
  console.log('contentWindow: dragleave');
  console.log(e.dataTransfer.getData('text/html'));
};

Первоначально я ожидал, что это будет простая процедура перетаскивания, но получение [object HTMLDivElement] в журналах и при вставке оказалось головной болью. Куда я иду не так?

1 Ответ

0 голосов
/ 04 июня 2019

Получается, по какой-то причине вам нужно использовать e.dataTransfer.setData('text/plain', e.target.id) и e.target.appendChild(document.getElementById(e.dataTransfer.getData('text/plain')).cloneNode(true)), если вы копируете элемент, или удалить .cloneNode(true), если вы перемещаете элемент.

Вот обновленный скрипт, fallback - это просто элемент dropzone вместе с iframe, я проверял, чтобы убедиться, что он работает для обоих, а не только для родительского документа.

const element = document.querySelector('.draggable');
const iframe = document.querySelector('iframe');
const iframeBody = iframe.contentDocument.querySelector('body');
const fallback = document.querySelector('.dropzone-fallback');

element.ondragstart = e => {
  console.log('mainWindow: dragstart');
  element.id = 'draggable';
  e.dataTransfer.setData('text/plain', e.target.id);
  e.dataTransfer.dropEffect = 'copy';
};

iframe.contentWindow.ondragenter = e => {
  e.preventDefault();
  iframeBody.style.transition = '0.5s';
  iframeBody.style.opacity = 0.5;
  // e.dataTransfer.dropEffect = 'copy';
  console.log('contentWindow: dragenter');
};

fallback.ondragenter = e => {
  e.preventDefault();
  // e.dataTransfer.dropEffect = 'copy';
};

iframe.contentWindow.ondragover = e => {
  e.preventDefault();
  e.dataTransfer.dropEffect = 'copy';
  console.log(e.dataTransfer.getData('text/plain'));
};

fallback.ondragover = e => {
  e.preventDefault();
  e.dataTransfer.dropEffect = 'copy';
};

iframe.contentWindow.ondrop = e => {
  e.preventDefault();
  console.log('contentWindow: drop');
  const data = e.dataTransfer.getData('text/plain');
  e.target.appendChild(document.getElementById(data));
};

fallback.ondrop = e => {
  e.preventDefault();
  const data = e.dataTransfer.getData('text/plain');
  e.target.appendChild(document.getElementById(data).cloneNode(true));
};

iframe.contentWindow.ondragleave = e => {
  iframeBody.style.opacity = 1;
  console.log('contentWindow: dragleave');
};

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...