Desativar arrastar e soltar em elementos HTML?

109

Estou trabalhando em um aplicativo da web para o qual estou tentando implementar um sistema de janelas completo. No momento está indo muito bem, estou encontrando apenas um pequeno problema. Às vezes, quando vou arrastar uma parte do meu aplicativo (na maioria das vezes o div do canto da janela, que deve acionar uma operação de redimensionamento), o navegador da web fica esperto e pensa que quero arrastar e soltar alguma coisa. Resultado final, minha ação é colocada em espera enquanto o navegador arrasta e solta.

Existe uma maneira fácil de desativar o recurso de arrastar e soltar do navegador? Eu gostaria de poder desligá-lo enquanto o usuário clica em certos elementos, mas reativá-lo para que os usuários ainda possam usar a funcionalidade normal de seu navegador no conteúdo de minhas janelas. Estou usando o jQuery e, embora não tenha conseguido encontrá-lo navegando na documentação, se você conhece uma solução jQuery pura, seria excelente.

Resumindo: preciso desabilitar a seleção de texto do navegador e as funções de arrastar e soltar enquanto meu usuário mantém o botão do mouse pressionado e restaurar essa funcionalidade quando o usuário libera o mouse.

Nicholas Flynt
fonte
2
Eu promoveria que a resposta de @ SyntaxError (abaixo, mais de 100 votos) deve ser a resposta selecionada, pois não afeta as operações de não arrastar.
Shaun Wilson

Respostas:

78

Tente evitar o padrão no evento mousedown:

<div onmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false">asd</div>

ou

<div onmousedown="return false">asd</div>
Sergey Ilinsky
fonte
2
+1 - no entanto, isso tem o efeito colateral infeliz no Firefox (6.0 e inferior), onde impede que a :activepseudo-classe seja aplicada ao elemento. Isso significa que não posso realmente usá-lo para meus links.
Andy E
3
Desculpe, isso é terrível. Veja a resposta abaixo.
Madbreaks
216

Essa coisa funciona ... Experimente.

<BODY ondragstart="return false;" ondrop="return false;">

espero que ajude. obrigado

Erro de sintaxe
fonte
6
Funciona bem! (Os atributos também podem ser colocados em um <div>elemento.)
VasiliNovikov
4
votou nesta resposta. A resposta mousedown IMO é muito curta (você pode usar o evento mousedown para outros casos). Esta resposta funcionou perfeitamente bem :)
Daniel van Dommele
4
Esta é realmente uma resposta muito melhor, tendo 'preventDefault ()' no mouse pressionado tem muitos efeitos colaterais (por exemplo, para evitar o foco / desfoque de entradas de texto de formulário)
Jecimi
Essa deve ser a resposta aceita, pois não afetará a ação do clique.
rafaelmorais de
Isso, juntamente com um copy pasteouvinte, parece ser a solução perfeita para forçar um usuário a digitar a entrada em vez de colar / arrastar algo sem afetar adversamente outras partes da página.
Daniel Bonnell
12

Isso pode funcionar: você pode desativar a seleção com css3 para texto, imagem e basicamente tudo.

.unselectable {
   -moz-user-select: -moz-none;
   -khtml-user-select: none;
   -webkit-user-select: none;

   /*
     Introduced in IE 10.
     See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/
   */
   -ms-user-select: none;
   user-select: none;
}

Claro, apenas para os navegadores mais recentes. Para mais detalhes, verifique:

Como desativar o destaque de seleção de texto usando CSS?

Tosh
fonte
Muito obrigado. Eu quero um clicável div, mas com o arrasto desativado.
Ionică Bizău
@ Ionică Bizău Se você quiser tornar as coisas clicáveis, é melhor usar um botão ou uma etiqueta, já que certos dispositivos sem mouse e telas sensíveis ao toque irão reconhecê-los e torná-los selecionáveis ​​para os usuários.
Tosh
8

Com jQuery será algo assim:

$(document).ready(function() {
  $('#yourDiv').on('mousedown', function(e) {
      e.preventDefault();
  });
});

No meu caso, eu queria desabilitar o usuário de soltar texto nas entradas, então usei "drop" em vez de "mousedown".

$(document).ready(function() {
  $('input').on('drop', function(event) {
    event.preventDefault();
  });
});

Em vez disso, event.preventDefault () você pode retornar false. Aqui está a diferença.

E o código:

$(document).ready(function() {
  $('input').on('drop', function() {
    return false;
  });
});
Victor Romano
fonte
2

Este é um violino que sempre uso com meus aplicativos da Web:

$('body').on('dragstart drop', function(e){
    e.preventDefault();
    return false;
});

Isso impedirá que qualquer coisa em seu aplicativo seja arrastada e solta. Dependendo das necessidades do tour, você pode substituir o seletor de corpo por qualquer recipiente que as crianças não devam ser arrastadas.

Lis
fonte
0

tente isso

$('#id').on('mousedown', function(event){
    event.preventDefault();
}
Crazyjune
fonte
0

Para os inputelementos, essa resposta funciona para mim.

Implementei em um componente de entrada customizado no Angular 4, mas acho que poderia ser implementado com JS puro.

HTML

<input type="text" [(ngModel)]="value" (ondragenter)="disableEvent($event)" 
(dragover)="disableEvent($event)" (ondrop)="disableEvent($event)"/>

Definição de componente (JS):

export class CustomInputComponent { 

  //component construction and attribute definitions

  disableEvent(event) {
    event.preventDefault();
    return false;
  }
}
Tito Leiva
fonte
0

usando a resposta de @ SyntaxError, https://stackoverflow.com/a/13745199/5134043

Consegui fazer isso no React; a única maneira que consegui descobrir foi anexar os métodos ondragstart e ondrop a um ref, assim:

  const panelManagerBody = React.createRef<HTMLDivElement>();
  useEffect(() => {
    if (panelManagerBody.current) {
      panelManagerBody.current.ondragstart = () => false;
      panelManagerBody.current.ondrop = () => false;
    }
  }, [panelManagerBody]);

  return (
    <div ref={panelManagerBody}>
Kriskate
fonte
0

Vou apenas deixar aqui. Me ajudou depois que tentei de tudo.

   $(document.body).bind("dragover", function(e) {
        e.preventDefault();
        return false;
   });

   $(document.body).bind("drop", function(e){
        e.preventDefault();
        return false;
   });
Checknov
fonte
-1

Este JQuery funcionou para mim: -

$(document).ready(function() {
  $('#con_image').on('mousedown', function(e) {
      e.preventDefault();
  });
});
Piyush
fonte