React-dnd: Проблемы с вводом и текстовыми полями внутри перетаскиваемого компонента

Созданный на 2 июн. 2015  ·  17Комментарии  ·  Источник: react-dnd/react-dnd

Я исследую некоторые проблемы при размещении элементов <input> и <textarea> внутри перетаскиваемого компонента,

  1. Ярлыки cmd+A или Ctrl+A не работают для ввода или текстового поля (но выбор текста с помощью Shift + Arrows прежнему работает)
  2. Попытка выбрать ввод или содержимое текстового поля с помощью сенсорной панели / мыши начинает перетаскивать родительский элемент

Мой перетаскиваемый компонент выглядит так:

draggable component

Самый полезный комментарий

Элементы с contentEditable, установленные внутри перетаскиваемого родительского контейнера, не позволили бы мне выделять текст или каким-либо образом взаимодействовать с ними. Покопавшись, я нашел этот отчет об ошибке: https://bugs.chromium.org/p/chromium/issues/detail?id=170139

Похоже, с тех пор Chrome исправил проблему. Тем временем поведение Safari можно исправить с помощью CSS:

.contenteditable-element {
  user-select: text;
}

Все 17 Комментарий

Это вызвано регистрацией события selectstart , которое очевидно необходимо только для совместимости с IE.
Если, как и я, вам не нужна совместимость с IE, вот мое быстрое исправление, которое может сработать для вас:
https://github.com/dperetti/react-dnd/commit/06f74ef97e07a9a24c10eab8593f3e2121d4f2ed

Спасибо за сообщение! Я рад принять пиар, исправляющий это.

У меня два требования:

  • Это исправление для IE необходимо.
  • Проверьте, требуется ли preventDefault() для других браузеров. Я думаю, это предотвращает выделение текста всего, что вы пытались перетащить. Если это действительно помогает предотвратить нежелательный выбор в других браузерах, вы можете окружить e.preventDefault() некоторой проверкой а-ля e.target.tagName !== 'input' (но более умной).

Та же ошибка с <div contentEditable={isEditing} /> .
Также я не могу его редактировать. Ctrl+A и Shift + Arrows не работают.

В следующие три недели я буду занят, и у меня нет времени на то, чтобы это исправить.
Как я уже сказал, я рад принять PR с исправлением, как описано в https://github.com/gaearon/react-dnd/issues/178#issuecomment -108110202.

Изучал это. Если я закомментирую все тело функции handleSelectStart , все будет работать должным образом. Протестировал это в IE11 и, похоже, там тоже все хорошо.

@gaearon знаете ли вы, есть ли конкретный вариант использования или настройка, почему событие вообще необходимо обрабатывать? IE10? Установка отличается от textarea / input в перетаскиваемом узле? У меня нет проблем с выделением текста, и мне интересно, работает ли CSS user-select над этим, если необходимо, над preventDefault .

Первоначальная проблема была https://github.com/gaearon/react-dnd/issues/128.
Если вы можете подготовить PR, который устраняет проблему, но при этом поддерживает работу https://github.com/gaearon/react-dnd/issues/128 , это будет огромным подспорьем.

Посмотрим, смогу ли я разобраться в этом. Необходимо найти способ настроить простой тестовый пример для IE9.

Я думаю, что пример sortable-simple завершился неудачно в IE9 до исправления # 128.

@gaearon Да, это хороший пример для использования, спасибо. Несколько примечаний:

  1. Никакие другие браузеры (протестированные последние версии Chrome, Safari, FF и IE 11), похоже, не заботятся об этом. Событие вообще не нужно обрабатывать.
  2. IE9, кажется, только _надает_ вызов e.target.dragDrop() . Отключить выделение текста можно, создав дескриптор, который покрывает весь перетаскиваемый объект, заключив перетаскиваемый узел в connectDragPreview а дескриптор в connectDragSource . Хотя это может показаться неприятным, но на самом деле вы официально не поддерживаете IE9, так что это разумный обходной путь, особенно когда в этом браузере могут возникнуть другие проблемы?
  3. Пункт номер два также полезен в любом случае, если у вас есть ввод текста в перетаскиваемом элементе. Пользователи не могут выбрать текст, перетаскивая мышку, если connectDragSource применяется ко всему узлу (в результате перетаскивается узел вместо выделения текста), однако применяется к невидимому дескриптору, который является размером всего узла работает очень красиво.

Не знаете, как вы хотите с этим справиться. Не прибегая к проверке UA, я не знаю, есть ли отличный способ справиться с этим, и мне кажется, что он добавляет функциональность для поддержки неофициально поддерживаемого браузера, что нарушает работу хороших браузеров, что может в конечном итоге вырыть дыру в обслуживании. Но это все мое мнение. Тем не менее, есть обходной путь к этой проблеме, который также решает другие проблемы.

Удаление прослушивателя событий для selectstart заставляет contentEditable работать в Chrome, но по-прежнему не работает в Safari.

Исправлено https://github.com/gaearon/react-dnd/commit/0a36033693868a7985ea2348105da4fb2cef8a00.

Удаление прослушивателя событий для selectstart позволяет contentEditable работать в Chrome, но по-прежнему не работает в Safari.

Это проблема API перетаскивания HTML5 в Safari. Мы ничего не можем с этим поделать.

Исправление этой проблемы было выпущено в [email protected] .
Убедитесь, что это работает.

Подтверждено, что Ctrl / Cmd-A работает в <input> внутри перетаскиваемого компонента.

Попытка выбрать ввод или содержимое текстового поля с помощью сенсорной панели / мыши начинает перетаскивать родительский элемент

Я вижу, что это не исправлено, создать новую проблему?

Элементы с contentEditable, установленные внутри перетаскиваемого родительского контейнера, не позволили бы мне выделять текст или каким-либо образом взаимодействовать с ними. Покопавшись, я нашел этот отчет об ошибке: https://bugs.chromium.org/p/chromium/issues/detail?id=170139

Похоже, с тех пор Chrome исправил проблему. Тем временем поведение Safari можно исправить с помощью CSS:

.contenteditable-element {
  user-select: text;
}

@trevorsmith Это все еще не исправляет поведение Firefox. Вы знаете какое-либо решение для Firefox?

@ rahul1995 - Я только что нашел решение: просто сохраните false :

const Test = () => {
  const ref = useRef(null);
  const [focused, setFocused] = useState(false);
  const [_, drag] = useDrag({ item: { type: 'test' } });

  useEffect(() => {
    if (ref.current) {
      ref.current.setAttribute('draggable', !focused);
    }
  }, [focused]);

  return drag(
    <textarea ref={ref} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}></textarea>
  );
};

Это должно помочь Firefox: wink:

Была ли эта страница полезной?
0 / 5 - 0 рейтинги