React-dnd: Problemas com entradas e áreas de texto dentro do componente arrastável

Criado em 2 jun. 2015  ·  17Comentários  ·  Fonte: react-dnd/react-dnd

Investigo alguns problemas ao colocar elementos <input> e <textarea> dentro do componente arrastável,

  1. cmd+A ou Ctrl+A atalhos não funcionam para entrada ou textarea (mas selecionar texto com Shift + Arrows ainda funciona)
  2. A tentativa de selecionar o conteúdo de entrada ou área de texto com o touchpad / mouse começa a arrastar o elemento pai

Meu componente arrastável parece,

draggable component

bug

Comentários muito úteis

Elementos com contentEditable definido dentro de um contêiner pai arrastável não me permitiriam selecionar texto ou interagir com eles de qualquer maneira. Depois de algumas pesquisas, encontrei este relatório de bug: https://bugs.chromium.org/p/chromium/issues/detail?id=170139

Parece que o Chrome já corrigiu o problema. O comportamento do Safari pode ser corrigido entretanto com CSS:

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

Todos 17 comentários

Isso é causado pelo registro do evento selectstart , que aparentemente só é necessário para compatibilidade com o IE.
Se, como eu, você não precisa de compatibilidade com o IE, aqui está minha solução rápida que pode funcionar para você:
https://github.com/dperetti/react-dnd/commit/06f74ef97e07a9a24c10eab8593f3e2121d4f2ed

Obrigado por relatar! Fico feliz em aceitar um PR consertando isso.

Tenho dois requisitos:

  • Ele ainda precisa ter aquela correção do IE.
  • Verifique se preventDefault() é necessário para os outros navegadores. Acho que impede a seleção de texto de tudo o que você tentou arrastar. Se realmente ajudar a prevenir a seleção indesejada em outros navegadores, você pode querer cercar e.preventDefault() com alguns cheques a la e.target.tagName !== 'input' (mas um mais inteligente).

Mesmo bug com <div contentEditable={isEditing} /> .
Também não posso editá-lo. Ctrl+A e Shift + Arrows não funcionam.

Nas próximas três semanas estarei ocupado e não tenho tempo para consertar isso.
Como eu disse, estou feliz em aceitar um PR com uma correção, conforme descrito em https://github.com/gaearon/react-dnd/issues/178#issuecomment -108110202.

Estava investigando isso. Se eu comentar todo o corpo da função handleSelectStart , tudo funcionará conforme o esperado. Testei isso no IE11 e parece ser bom lá também.

@gaearon , você sabe se há um caso de uso específico ou configuração para explicar por que o evento precisa ser tratado? IE10? Configuração diferente de textarea / input em um nó arrastável? Não recebo problemas de seleção de texto e me pergunto se o CSS user-select contorna isso mais de preventDefault se necessário.

O problema original era https://github.com/gaearon/react-dnd/issues/128.
Se você puder preparar um PR que resolva o problema, mas também mantenha https://github.com/gaearon/react-dnd/issues/128 funcionando, isso seria de grande ajuda.

Vou ver se consigo investigar. Precisa descobrir uma maneira de configurar um caso de teste simples para o IE9.

Acho que sortable-simple exemplo falhou no IE9 antes que # 128 fosse corrigido.

@gaearon Sim, esse foi um bom exemplo para usar, obrigado. Algumas notas:

  1. Nenhum outro navegador (mais recente Chrome, Safari, FF e IE 11 testado) parece se importar com isso. O evento não precisa ser tratado de forma alguma.
  2. O IE9 só parece _precisar_ da chamada e.target.dragDrop() . A desativação da seleção de texto pode ser feita criando uma alça que cobre todo o objeto arrastável, envolvendo o nó arrastável em connectDragPreview e a alça em connectDragSource . Embora isso possa parecer desagradável, AFAIK, você não está oficialmente apoiando o IE9, então essa é uma solução razoável, especialmente quando outros problemas podem surgir nesse navegador?
  3. O ponto número dois também é útil de qualquer maneira, no caso de você ter uma entrada de texto dentro do arrastável. Os usuários não podem selecionar o texto arrastando seus ratos se connectDragSource for aplicado a todo o nó (isso acaba arrastando o nó em vez de selecionar o texto), porém aplicando a uma alça invisível que é do tamanho de todo o nó funciona muito bem.

Não tenho certeza de como você deseja lidar com isso. Sem recorrer à verificação do UA, não sei se há uma ótima maneira de lidar com isso e me parece que está adicionando funcionalidade para oferecer suporte a um navegador com suporte não oficial que está quebrando bons navegadores que podem acabar cavando um buraco de manutenção. Mas isso é tudo minha opinião. Independentemente disso, há uma solução alternativa para esse problema que também resolve outros problemas.

Remover o ouvinte de eventos de selectstart faz contentEditable funcionar no Chrome, mas ainda não está funcionando no Safari.

Corrigido por https://github.com/gaearon/react-dnd/commit/0a36033693868a7985ea2348105da4fb2cef8a00.

Remover o ouvinte de evento para selectstart torna contentEditable funcionar no Chrome, mas ainda não está funcionando no Safari.

Este é o problema da API de arrastar e soltar do HTML5 no Safari. Não podemos fazer nada a respeito.

A correção para esse problema foi lançada em [email protected] .
Verifique se funciona.

Confirmado que Ctrl / Cmd-A funciona em <input> dentro de um componente arrastável.

A tentativa de selecionar o conteúdo de entrada ou área de texto com o touchpad / mouse começa a arrastar o elemento pai

Vejo que isso não foi corrigido, criar um novo problema?

Elementos com contentEditable definido dentro de um contêiner pai arrastável não me permitiriam selecionar texto ou interagir com eles de qualquer maneira. Depois de algumas pesquisas, encontrei este relatório de bug: https://bugs.chromium.org/p/chromium/issues/detail?id=170139

Parece que o Chrome já corrigiu o problema. O comportamento do Safari pode ser corrigido entretanto com CSS:

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

@trevorsmith Isso ainda não

@ rahul1995 - Acabei de descobrir uma solução: basta armazenar um ref no nó DOM arrastável e quando o usuário focar input / textarea definir o atributo draggable para 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>
  );
};

Isso deve servir para o Firefox: wink:

Esta página foi útil?
0 / 5 - 0 avaliações