Когда контекст, источник и цель находятся внутри iframe, DnD не может быть отменен. Я отследил его до бэкэнда HTML5.js, который поставляется с DnD.
Хотя я думаю, что это может быть связано с перерисовкой в iframe. Вот пример кода http://codepen.io/mattconde/pen/zGLXML?editors=101
Изначально перетаскивание между кадрами у меня тоже не работало. Похоже, что события перетаскивания / перетаскивания просто необходимо применить к каждому объекту окна дополнительного фрейма. В настоящее время их получает только объект окна, в котором вы запускаете приложение реакции:
https://github.com/gaearon/react-dnd/blob/master/src/backends/HTML5.js#L130 -L139
Я исправил HTML5-бэкэнд в своем недавнем проекте, чтобы заставить его работать ( setup
и teardown
принимают альтернативный объект win
window):
https://gist.github.com/rasmusfl0e/39db428399bd196ef706
Это также требует, чтобы экземпляр серверной части был каким-то образом открыт (больше исправлений обезьяны в DragDropContext.js
...) для выполнения setup
и teardown
при необходимости (при настройке ваших фреймов) .
Но как только это будет сделано - это работает как шарм: D
Ого, хорошая находка, в ней много смысла. Собираясь попробовать это позже сегодня, можно ли избежать изменения DragDropContext.js? Таким образом, мы могли бы просто создать новый бэкэнд, как упоминается в документации.
Я рад рассмотреть конкретный API и предложение по реализации для решения этой проблемы.
К сожалению, трудно понять, что именно было изменено и почему.
На данный момент допустим, что мы не поддерживаем фреймы.
@gaearon Я пытаюсь создать конструктор страниц с перетаскиванием. Пробовал все остальное и они ужасно работают с флюсом. Можете дать мне несколько подсказок, где настроить, чтобы он работал с перекрестным фреймом?
@nadimtuhin Я сам работал над
Я не уверен, что работа внутри iframe больше будет лучшим решением, это было бы хорошо. Но цель заставить react-dnd работать в нескольких приложениях - лучший вариант.
Вчера я кратко изучил это и просто зарегистрировал некоторые дескрипторы в бэкэнде html5. и источник из первого окна обнаруживается на цели из второго. Но это все, что я получил.
@gaearon Несколько указателей / подсказок о том, где искать, было бы здорово, если я хочу сделать / попробовать свои первые настоящие вклады с открытым исходным кодом.
@mattconde нет, я не управляю iframe внутри своего приложения для реагирования. Я планирую установить два разных приложения на двух разных фреймах. Родительское окно содержит логику для манипулирования данными, а дочерний фрейм - для представления. Дочерний элемент получает свои реквизиты из родительского хранилища потоков.
@mattconde
Мне трудно дать какие-либо указания, кроме «попробуйте поместить журналы в бэкэнд HTML5, а затем начните его настраивать». Возьмите простейший пример и посмотрите, сможете ли вы заставить его работать. Бэкэнд делает только одно: подписывается на события окна и события узла и преобразует их в действия. Я недостаточно знаю, как работают фреймы. Возможно, вам нужно изменить код, чтобы подписаться не на окно, а на окно верхнего уровня определенного узла (или iframe), если это имеет смысл. Но я здесь совсем не в себе, так что могу говорить чушь.
@mattconde @gaearon
Недавно у меня была такая же проблема. Причина сбоя в том, что HTML5Backend устанавливает прослушиватели событий в окне, но если вы хотите использовать его внутри iframe, вам лучше установить их, скажем, в window.frames [0].
@gaearon Что вы думаете о возможности передачи контекста в функцию настройки / удаления в HTML5Backend.js?
Я столкнулся с той же проблемой, создав расширенный редактор (текст, изображения, ..), который работает в iframe, и мне нужно перетаскивать элементы (текст, img) внутри него, в основном перетаскивая элементы, чтобы изменить заказ.
Я открыл проблему https://github.com/gaearon/react-dnd/issues/435 и просто понял, что это из-за iframe. Я попытаюсь "настроить это", но если есть какое-то решение, я был бы рад узнать! :)
Я пытаюсь сделать пиар, чтобы он работал с фреймами. В настоящее время выполняется, но пока не работает, мне сложно понять, как вызвать setup
и teardown
соответственно в моих componentDidMount
и componentWillUnmount
методы.
@Vadorequest Похоже, мы оба стремимся к одинаковому конечному продукту. Мне не удалось заставить его работать с react-dnd
от родительского к дочернему окну. Работа, на которой я остановился, заключалась в наличии моего приложения-редактора (родительского) и предварительного просмотра (дочернего) приложения. Приложение предварительного просмотра не отображалось до тех пор, пока не подключилось к магазину redux для редакторов.
Затем в моем магазине redux у меня был список шаблонов, которые я хочу, чтобы пользователь перетащил из редактора на страницу с отличным контентом. Итак, мой список шаблонов находился в окне редактора, но я бы хотел перетащить их в окно предварительного просмотра.
Благодаря поддержке собственных типов react-dnd
я мог настроить перетаскивание текста в окне редактора, чтобы передавать информацию, необходимую для каждого шаблона, который будет отображаться. Мой фрагмент кода ...
componentDidMount() {
this.refs.template.addEventListener('dragstart', this.handleDragStart, false);
},
componentWillUnmount() {
this.refs.template.removeEventListener('dragstart', this.handleDragStart, false);
},
handleDragStart(e) {
const { template } = this.props;
e.dataTransfer.setData('text/plain', JSON.stringify({
type: template.type,
name: template.name,
}));
return e;
},
Тогда я мог бы поймать эту строку JSON на другом конце с react-dnd
, работает очень хорошо.
Дайте мне знать, как у вас дела, хотелось бы услышать об альтернативных способах решения этой проблемы.
@mattconde Я работаю над двумя отдельными ветками, некрасивым исправлением и настоящим исправлением для этого. Уродливое исправление просто изменяет эти строки в файле HTML5Backend.js
. Изменения можно посмотреть здесь: https://github.com/Gutenberg-Technology/react-dnd-html5-backend/commit/8b3d6a44b2cdbfe8d5bac025fc263715968d8b6c
_ (в основном он просто добавляет параметр target
к setup
и teardown
, в котором мой iframe используется по умолчанию, и возвращается к использованию window
. Исправление настолько уродлив, что на самом деле он потерпит неудачу, если не будет найден iframe, но на данный момент он подойдет.) _
Но это, скорее всего, не удастся в какой-то ситуации, если есть более одного iframe, так что это просто, чтобы избежать зависания. Лучшим решением было бы вручную вызвать setup
и teardown
в моем собственном коде, просто передав параметр target
для привязки и отмены привязки слушателей.
Спасибо за объяснение вашего решения, я обязательно улучшу свой PR, если найду лучший обходной путь в ближайшем будущем. :)
Привет, ребята, я сам столкнулся с этой проблемой, не могу понять, как связать окно с iframe. Например, я хочу иметь некоторый DragSource в окне, и я хочу создать некоторый DropTarget в iframe, даже если я настрою HTML5Backend, я не могу заставить его работать так ...
@mattconde Спасибо, что поделились этим. Думаю, я создаю аналогичный конечный продукт. Хуже всего то, что мы используем Angular 2. Я частично портировал response-dnd на Angular, но, в конце концов, столкнулся с проблемой iframe. Собираюсь попробовать свой путь.
@gaearon PR здесь ☝️ позволяют response-dnd поддерживать iframe. Если у вас есть какие-либо вопросы или вы хотите, чтобы я что-то изменил, дайте мне знать.
@kesne Вы новый сопровождающий? Вы можете просмотреть эти PR?
Привет @darthtrevino
Позволяют ли ваши изменения перетаскивать элемент со страницы во фрейм?
Я могу перетаскивать внутри рамки и снаружи.
Привет, @crysislinux , я собираюсь перенести эту библиотеку на Angular 2 и хотел бы увидеть, что вы, ребята, придумали. Вы бы хотели поделиться своим кодом? Благодаря!
есть ли способ удалить элементы, которые находятся за пределами iframe внутри iframe, например:
<DragDropContextProvider backend={HTML5Backend}>
<div>
<Item />
<Frame>
<div>
<Dustbin />
</div>
</Frame>
</div>
</DragDropContextProvider>
После долгих попыток мне удалось удалить элементы внутри iframe следующим образом:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import FrameComponent from 'react-frame-component';
class DragDropAwareIFrame extends Component {
static propTypes = {
innerRef: PropTypes.func,
};
static contextTypes = {
dragDropManager: PropTypes.object.isRequired,
}
constructor(props, context) {
super(props, context);
this.manager = this.context.dragDropManager;
}
componentDidMount() {
const iframe = ReactDOM.findDOMNode(this.iframe);
this.manager.getBackend().addEventListeners(iframe.contentWindow);
}
componentWillUnmount() {
const iframe = ReactDOM.findDOMNode(this.iframe);
this.manager.getBackend().removeEventListeners(iframe.contentWindow);
}
handleRef = (el) => {
this.iframe = el;
if (this.props.innerRef) this.props.innerRef(el);
}
render() {
const { innerRef, ...props } = this.props;
return <FrameComponent {...props} ref={this.handleRef} />;
}
}
<DragDropContextProvider backend={HTML5Backend}>
<div>
<Item />
<DragDropAwareIFrame>
<div>
<Dustbin />
</div>
</DragDropAwareIFrame>
</div>
</DragDropContextProvider>
Кажется, это правильный способ сделать это?
@ethanve Просто случайно наткнулся на эту https://cormacrelf.github.io/angular-skyhook/
У меня также возникают проблемы с использованием dnd в iframe (без взаимодействия с родителями). Перетаскивание работает нормально, но зоны перетаскивания больше не работают. Каково решение, чтобы зоны перетаскивания работали внутри iframe (просто перемещая элемент полностью внутри iframe).
Я хочу указать, что он работает с бэкэндом Touch, но не с бэкэндом HTML5.
Самый полезный комментарий
После долгих попыток мне удалось удалить элементы внутри iframe следующим образом:
Кажется, это правильный способ сделать это?