Questões gerais e teoria da tecnologia Drag and Drop. Tecnologia de arrastar e soltar no Android Veja o que é "arrastar e soltar" em outros dicionários

182

Neste exemplo, selecionamos um elemento div e o tornamos móvel chamando-o método arrastável(). Conforme mostrado na figura abaixo, no documento aberto, o elemento assume sua posição usual, mas depois disso pode ser movido com o ponteiro do mouse para qualquer lugar na janela do navegador:

O recurso de arrastar e soltar é útil por si só, mas é ainda mais útil quando usado em conjunto com a interação Droppable, descrita a seguir.

A interação arrastável é implementada apenas por meio do uso de marcação HTML e estilos CSS específicos. Isso significa que essa funcionalidade funcionará em quase todos os navegadores, mas os elementos dotados dela não poderão funcionar com recursos nativos semelhantes de arrastar e soltar. sistemas operacionais.

As operações de arrastar e soltar definidas pela especificação HTML5 geralmente são implementadas usando mecanismos nativos do sistema operacional. Se você estiver usando o mecanismo de arrastar e soltar do jQuery UI, é melhor desativar os equivalentes do HTML5 para evitar conflitos. Para fazer isso, defina o atributo arrastável do elemento do corpo do documento como falso.

Personalizando a interação arrastável

Existem muitas opções de personalização para interação Draggable. As propriedades mais importantes abordadas nas seções a seguir estão resumidas na tabela abaixo:

Propriedades de interação arrastáveis
Propriedade Descrição
eixo Restringe o movimento a certas direções. O valor padrão é falso, o que significa que não há restrições, mas você também pode especificar o valor "x" (mover somente ao longo do eixo x) ou "y" (mover somente ao longo do eixo y)
contenção Restringe a localização do elemento flutuante a uma área específica da tela. Os tipos de valor suportados são descritos na tabela abaixo, com o exemplo correspondente. O valor padrão é falso, significa que não há restrições
atraso Especifica a quantidade de tempo que um elemento deve ser arrastado antes de se mover. O valor padrão é 0, o que significa nenhum atraso
distância Especifica a distância que o usuário deve arrastar um elemento de sua posição inicial antes que ele realmente se mova. O valor padrão é 1 pixel
grade Força a vinculação do elemento movido às células da grade. O valor padrão é false, o que significa que não há vinculação

Restrição de direções de movimento

Existem várias maneiras de restringir o movimento de um elemento em determinadas direções. A primeira delas é usar a opção de eixo, que permite limitar a direção do movimento ao eixo X ou Y. Um exemplo é mostrado abaixo:

...

Arraste verticalmente
Arraste horizontalmente
Exemplo de execução

Neste exemplo, definimos dois elementos div, os selecionamos com jQuery e chamamos o método draggable(). Este método recebe um objeto que inicialmente restringe ambos os divs para mover ao longo da direção x. Aplicando então o método jQuery filter(), podemos selecionar o elemento dragV sem pesquisar novamente com jQuery em todo o documento e defini-lo como outra direção de movimento permitida - ao longo do eixo Y. Assim, obtemos um documento no qual um elemento div só pode ser arrastado na direção vertical e o outro - apenas na direção horizontal. O resultado é mostrado na figura:

Restringindo a área permitida para mover um elemento

Você também pode limitar a área da tela onde pode arrastar um elemento. Para isso, é utilizada a opção de contenção. Os formatos de valor que podem ser especificados nesta opção estão descritos na tabela abaixo:

Um exemplo de uso da opção de contenção é mostrado abaixo:

...

Arraste horizontalmente
Arraste para dentro do pai
Exemplo de execução

Neste exemplo, ambos os elementos são obrigados a se mover para que possam ser arrastados apenas dentro do elemento pai, que é um elemento div de tamanho fixo. Um dos divs flutuantes tem uma restrição adicional, usando a opção de eixo, que só pode se mover horizontalmente dentro do elemento pai. O resultado é ilustrado na figura:

Restringindo a capacidade de mover um elemento para as células da grade

A opção de grade permite definir a ligação do elemento movido às células da grade. Esta opção aceita uma matriz de dois elementos que especifica a largura e a altura das células da grade em pixels. Um exemplo de uso da opção de grade é mostrado abaixo:

...

arraste-me
Exemplo de execução

Neste exemplo, a grade é definida para 100 pixels de largura e 50 pixels de altura. Quando você arrasta um elemento, ele "pula" de uma célula (invisível) para outra. O efeito de encaixe é um ótimo caso de uso para a funcionalidade de interação, mas é difícil transmitir com capturas de tela.

Você pode criar um efeito de encaixe para apenas uma direção definindo o eixo de movimento livre como 1. Por exemplo, se você definir a opção de grade como , o elemento se encaixará em células de grade de 100px de largura ao se mover horizontalmente, mas se moverá livremente verticalmente .

atraso de viagem

Existem duas opções que permitem atrasar o arrasto de um elemento flutuante. Com a opção de atraso, você pode definir o tempo em milissegundos que o usuário deve arrastar o ponteiro do mouse antes que o elemento seja realmente movido. Outro tipo de atraso é fornecido pela opção de distância, que especifica a distância, em pixels, que o usuário deve arrastar o ponteiro do mouse antes que um elemento o siga.

Um exemplo de uso de ambas as configurações é mostrado abaixo:

...

Bloqueio com atraso de tempo
Bloco com distância mínima
Exemplo de execução

Neste exemplo, existem dois elementos flutuantes, um dos quais tem um atraso definido com a opção de atraso e o outro com a opção de distância.

No caso do atraso especificado pela opção de atraso, o usuário deve arrastar pelo tempo especificado antes de realmente mover o elemento. Neste exemplo, a duração deste intervalo é de 1000 ms. Não é necessário mover o mouse durante este tempo, mas o botão do mouse deve permanecer pressionado durante todo o período de atraso, após o qual o elemento pode ser movido movendo o mouse. Depois de decorrido o tempo de atraso, o elemento que está sendo movido se ajustará à posição do ponteiro do mouse, sujeito às restrições impostas pelas opções de grade, região e eixo discutidas anteriormente.

A opção de distância tem um efeito semelhante, mas neste caso o usuário deve arrastar o ponteiro do mouse pelo menos o número especificado de pixels em qualquer direção a partir do local inicial do elemento. O item que está sendo movido pulará para o local atual do ponteiro.

Se você aplicar ambas as configurações ao mesmo elemento, o elemento que está sendo movido não se moverá até que ambos os critérios de atraso sejam atendidos, ou seja, até que a tentativa de arrastar o elemento dure o tempo especificado e até que o ponteiro do mouse mova o número especificado de pixels.

Usando métodos de interação arrastáveis

Todos os métodos definidos para a interação Draggable fazem parte do conjunto de métodos básicos que você já viu em widgets. Métodos específicos para a interação Draggable não são fornecidos, então não vamos abordá-los em detalhes. A lista de métodos disponíveis é mostrada na tabela abaixo:

Usando eventos de interação arrastáveis

A interação arrastável suporta um conjunto simples de eventos que notificam quando um elemento está sendo arrastado. Esses eventos estão descritos na tabela abaixo:

Assim como os eventos do widget, esses eventos também podem ser reagidos. Um exemplo de manipulação dos eventos start e stop é mostrado abaixo:

...

arraste-me
Exemplo de execução

Este exemplo usa os eventos start e stop para alterar o conteúdo do texto de um elemento durante o processo de arrastar. Essa vantagem vem do fato de que a interação do Draggable é implementada inteiramente usando HTML e CSS: você pode usar jQuery para alterar o estado de um elemento arrastável mesmo enquanto ele se move pela tela.

Usando a interação Droppable

Em algumas situações, arrastar um elemento sozinho pode ser suficiente, mas é mais útil quando usado em conjunto com a interação Droppable.

Elementos aos quais a interação Soltável foi aplicada (elementos de aceitação) ganham a capacidade de aceitar elementos soltos criados com a interação Arrastável.

Os elementos receptores são criados com método droppable(), mas para obter uma funcionalidade útil, você precisará criar manipuladores de eventos entre aqueles definidos para esse tipo de interação. Os eventos disponíveis são mostrados na tabela abaixo:

Eventos de interação dropáveis
Evento Descrição
criar Ocorre quando uma interação Droppable é aplicada a um elemento
ativar Ocorre quando o usuário começa a arrastar um elemento flutuante
desativar Ocorre quando o usuário para de arrastar um elemento flutuante
sobre Ocorre quando o usuário arrasta um elemento flutuante sobre o elemento receptor (mas assumindo que o botão do mouse ainda não foi liberado)
fora Ocorre quando o usuário arrasta um elemento flutuante para fora do elemento receptor
derrubar Ocorre quando o usuário deixa um elemento flutuante no elemento receptor

Um exemplo de criação de um elemento de recebimento simples que possui um único manipulador de evento drop é fornecido abaixo:

...

saia daqui
arraste-me
Exemplo de execução

Neste exemplo, um elemento div é adicionado ao documento, cujo conteúdo de texto é representado pela string "Deixe aqui". Selecionamos esse elemento usando jQuery e chamamos o método droppable(), passando para ele um objeto de configurações que define um manipulador para o evento drop. A resposta a esse evento é alterar o texto do elemento flutuante usando o método text().

A interação de arrastar e soltar que criamos neste exemplo é a mais simples, mas fornece um contexto útil para explicar como as interações arrastáveis ​​e soltáveis ​​funcionam juntas. As diferentes etapas do processo de arrastar e soltar elementos são ilustradas na figura:

Tudo isso parece muito simples. Arrastamos o elemento que está sendo movido até que esteja acima do elemento receptor e o soltamos. O elemento solto permanece onde foi deixado e seu conteúdo de texto muda em resposta à ocorrência do evento drop. As seções a seguir mostram como usar outros eventos de interação do Droppable para melhorar a experiência do usuário.

Alvo Recebendo Destaque do Objeto

Ao usar os eventos activate e deactivate, você pode realçar o objeto receptor de destino quando o usuário iniciar o processo de arrastar um elemento. Em muitas situações, essa ideia é muito proveitosa porque dá ao usuário uma indicação confiável de quais elementos fazem parte do modelo de arrastar e soltar. O exemplo relevante é mostrado abaixo:

... $(function() ( $("#draggable").draggable(); $("#droppable").droppable(( drop: function() ( $("#draggable").text("Descartou ") ), active: function() ( $("#droppable").css(( border: "medium double green", backgroundColor: "lightGreen" )); ), deactive: function() ( $("#droppable ").css("borda", "").css("cor de fundo", ""); ) )); )); ... Execute o exemplo

Assim que o usuário começa a arrastar o elemento, o evento activate - associado ao nosso elemento receptor - é acionado, e a função do manipulador usa o método css() para alterar as propriedades CSS de borda e cor de fundo do elemento. Como resultado, o elemento receptor de destino é destacado, indicando ao usuário que existe uma conexão entre ele e o elemento que está sendo movido.

O evento deactivate é usado para remover valores de propriedade CSS do elemento receptor e devolvê-lo ao o estado inicial assim que o usuário soltar o botão do mouse. (Este evento é disparado sempre que o arrasto de um elemento para, independentemente de o elemento arrastado ser deixado no elemento receptor ou não.) Este processo é ilustrado na figura:

Manipulação de sobreposição de elementos

A tecnologia de arrastar e soltar pode ser aprimorada adicionando-se a manipulação de eventos over and out. O evento over ocorre quando 50% do elemento que está sendo movido está acima de qualquer parte do elemento receptor. O evento out é acionado quando os elementos sobrepostos anteriormente não se sobrepõem mais. Um exemplo de resposta a esses eventos é mostrado abaixo:

$(function() ( $("#draggable").draggable(); $("#droppable").droppable(( drop: function() ( $("#draggable").text("Dropped") ) , active: function() ( $("#droppable").css(( border: "medium double green", backgroundColor: "lightGreen" )); ), desative: function() ( $("#droppable"). css("border", "").css("background-color", ""); ), over: function() ( $("#droppable").css(( border: "medium double red", backgroundColor : "red" )); ), out: function() ( $("#droppable").css("border", "").css("background-color", ""); ) )); ) ); Exemplo de execução

As mesmas funções do manipulador são usadas aqui como no exemplo anterior, mas neste caso elas estão associadas aos eventos over e out. Quando pelo menos 50% do elemento flutuante se sobrepõe ao elemento receptor, ele é enquadrado e sua cor de fundo muda, conforme mostra a figura:

Esse limite de 50% é chamado de limite de tolerância, que pode ser definido no momento da criação do elemento receptor, conforme será mostrado a seguir.

Configuração de interação droppable

A interação Droppable tem várias propriedades que você pode modificar para personalizar seu comportamento. Essas propriedades estão listadas na tabela abaixo:

Propriedades de interação que podem ser soltas
Propriedade Descrição
desabilitado Se esta opção for verdadeira, a funcionalidade de interação droppable é inicialmente desativada. O valor padrão é falso
aceitar Limita o conjunto de elementos flutuantes aos quais o elemento receptor responderá. O valor padrão é *, corresponde a qualquer elemento
classe ativa Define uma classe que será atribuída em resposta ao evento activate e removida em resposta ao evento deactivate
hoverClass Define uma classe que será atribuída em resposta a um evento over e removida em resposta a um evento out.
tolerância Especifica o grau mínimo de sobreposição no qual ocorre o evento over

Restrição de elementos flutuantes permitidos

Você pode limitar o conjunto de elementos soltáveis ​​que serão aceitos por um elemento que tenha a funcionalidade de interoperabilidade Soltável usando a opção aceitar. O valor da opção aceitar deve ser um seletor. Como resultado desse evento, as interações droppable ocorrerão apenas se o elemento que está sendo movido corresponder ao seletor especificado. O exemplo relevante é mostrado abaixo:

...

saia daqui
Elemento 1
Elemento 2
Exemplo de execução

Neste exemplo, há dois elementos flutuantes com IDs drag1 e drag2. Ao criar um elemento aceitante, utiliza-se a opção aceitar, com a qual indicamos que somente o elemento drag1 será um elemento flutuante aceitável.

Ao arrastar o elemento drag1, você verá o mesmo efeito dos exemplos anteriores. Os eventos activate, deactivate, over e out dispararão no elemento receptor nos momentos apropriados. Ao mesmo tempo, se você arrastar um elemento drag2 que não corresponda ao seletor especificado no parâmetro aceitar, esses eventos não serão acionados. Este elemento pode ser movido livremente, mas não será aceito pelo elemento receptor.

Observe a mudança na maneira como você seleciona um elemento flutuante aceitável para chamar o método text(). Quando havia apenas um elemento flutuante no documento, o atributo id era suficiente para isso:

Soltar: function() ( $("#arrastável").text("Descartou") ),

Neste exemplo, existem dois elementos flutuantes, e selecionar pelo atributo id não dará o resultado desejado, pois o texto neste caso sempre mudará no mesmo elemento flutuante, independente de qual seja aceitável para o elemento receptor.

A solução é usar o objeto ui que o jQuery UI fornece como um argumento adicional para cada manipulador de eventos. A propriedade draggable do objeto ui retorna um objeto jQuery contendo o elemento que o usuário está arrastando ou tentando soltar no elemento alvo, permitindo que o elemento desejado seja selecionado da seguinte forma:

Drop: function(evento, ui) ( ui.draggable.text("Dropped") ),

Alterando o limite de sobreposição

Por padrão, o evento over só é acionado quando pelo menos 50% do elemento que está sendo movido se sobrepõe ao elemento receptor. A quantidade dessa sobreposição de limite pode ser alterada usando a opção de tolerância, que pode assumir os valores mostrados na tabela abaixo:

Os dois valores que mais uso, fit e touch, são os que fazem mais sentido para os usuários. Utilizo o valor fit quando o elemento arrastado deve permanecer na área do elemento receptor para onde foi movido, e o valor touch quando o elemento arrastado deve retornar à sua posição original (um exemplo será dado mais adiante). Um exemplo de uso dos parâmetros de ajuste e toque é mostrado abaixo:

O valor clone diz ao jQuery UI para criar uma cópia do elemento flutuante junto com todo o seu conteúdo e usar o resultado como um elemento auxiliar. O resultado é mostrado na figura:

O elemento auxiliar é removido quando o usuário solta o botão do mouse sobre o elemento que está sendo movido, deixando o elemento que está sendo movido e o elemento receptor em suas posições originais.

Conforme mostrado na figura, o elemento flutuante original permanece em seu lugar e apenas o elemento auxiliar se move pela tela seguindo o ponteiro do mouse. Se o tamanho do elemento que está sendo movido for grande, como em nosso exemplo, ele cobrirá o restante dos elementos do documento, portanto, será difícil para o usuário rastrear a posição do elemento receptor. Esse problema pode ser resolvido fornecendo uma função como valor da opção auxiliar, conforme exemplo abaixo:

... $(function() ( $("div.draggable")..png"/>") ) )); $("#cesta").droppable(( activeClass: "active", hoverClass: "hover" )); )); ... Execute o exemplo

Quando o usuário começa a arrastar um elemento, jQuery UI chama a função especificada pelo parâmetro auxiliar e usa o elemento retornado como o objeto de arrastar. Neste caso, estou usando jQuery para criar o elemento img. O resultado é mostrado na figura:

A imagem pequena atua como um espaço reservado para o elemento flutuante, tornando muito mais fácil acompanhar outros elementos no documento.

O objeto ui que o jQuery UI passa para os eventos de interação Droppable contém uma propriedade auxiliar, e essa propriedade pode ser usada para manipular o elemento auxiliar enquanto ele está sendo arrastado. Um exemplo de uso dessa propriedade em conjunto com os eventos over e out é mostrado abaixo:

... $(function() ( $("div.draggable")..png"/>") ) )); $("#basket").droppable(( activeClass: "active", hoverClass: "hover", over: function(event, ui) ( ui.helper.css("border", "thick solid #27e6ed") ) , out: function(evento, ui) ( ui.helper.css("border", "") ) )); )); ...

Aqui, os eventos over e out e a propriedade ui.helper são usados ​​para exibir uma borda ao redor do elemento auxiliar quando ele se sobrepõe ao elemento host. O resultado é mostrado na figura:

Ajustar às bordas dos elementos

usando opções de encaixeé possível conseguir que o elemento que está sendo movido seja "atraído" para as bordas dos elementos próximos aos quais passa. Esta opção leva um seletor como seu valor. O elemento flutuante se encaixará nas bordas de qualquer elemento que corresponda ao seletor especificado. Um exemplo de uso da opção snap é mostrado abaixo:

Exemplo de execução IU do jQuery

Cesta
Tether aqui
arraste-me

Quando um elemento móvel se aproxima de um dos elementos correspondentes, ele é meio que "puxado" para ele de tal forma que suas bordas adjacentes se tocam. Para tal ligação, você pode selecionar qualquer elemento, não apenas o receptor. Neste exemplo, adicionei um elemento div e defini a opção snap para um valor que seleciona esse elemento no documento, bem como o elemento receptor.

Existem algumas subopções que permitem ajustar como os elementos se comportam em relação à ancoragem. Um deles é opção snapMode. Ele pode ser usado para especificar o tipo de encadernação. Os seguintes valores são permitidos: interno(encaixe nas bordas internas dos elementos), exterior(encaixe nas bordas externas dos elementos) e ambos(encaixe em todas as arestas; padrão).

opção snapTolerance permite especificar a que distância o elemento flutuante deve se aproximar da borda do elemento de destino antes que ocorra o encaixe. O valor padrão é 20, o que significa 20 pixels. O exemplo usa um valor de 50, que corresponde a uma âncora a uma distância maior. É muito importante escolher o valor certo para esta opção. Se o valor da opção snapTolerance for muito baixo, o usuário pode não perceber o efeito de encaixe e, se for muito alto, o elemento que está sendo movido começará a pular inesperadamente, encaixando-se em elementos distantes.

Uso de tecnologia arraste e solte (arraste e solte) permite ao usuário mover vários objetos de uma para outra, por exemplo, elementos de uma lista para outra. Para fazer isso, você precisa usar dois controles: um coletor e uma fonte. O receptor é o objeto que receberá o objeto de origem (objeto móvel).

Os eventos que ocorrem durante o movimento dos objetos estão listados abaixo na ordem em que ocorrem.

OnStartDrag(tipo TStartDragEvent) - gerado pelo objeto fonte no início da operação. Parâmetros passados ​​para o manipulador de eventos: objeto receptor DragObject (tipo TdragObject), objeto Source (tipo TObject).

OnDragOver(tipo TDragOverEvent) - cria um objeto de destino quando um objeto flutuante é colocado acima dele. Parâmetros passados ​​para o manipulador de eventos: Objeto receptor remetente (tipo TObject), Objeto fonte fonte (tipo TObject), Estado do movimento do estado (tipo TdragState), X e Y (tipo inteiro) - coordenadas atuais do ponteiro do mouse, Accept (tipo booleano ) sinal de confirmação da operação de movimentação. O estado de movimento deixa claro se o objeto que está sendo movido está na área receptora, se ele se move nela, se saiu dela. Os parâmetros passados ​​permitem que o objeto receptor aceite ou rejeite o objeto fonte. O parâmetro Accept é definido como Trye se a operação de movimentação for aceita, caso contrário, False.

onDragDrop (tipo TDragDropEvent) - Gerado pelo objeto de destino quando o objeto arrastado é solto sobre ele. O manipulador de eventos recebe as coordenadas atuais do ponteiro do mouse, o objeto Receptor emissor (tipo TObject) e o objeto de movimento Source original (tipo TObject).

onEndDrag (tipo EndDragEvent) - Gerado quando uma operação de arrastar termina. As coordenadas X e Y do ponto onde o objeto Sender source e o objeto Target receiver são passados ​​para o manipulador de eventos.

Para criar um arrastar e soltar, basta implementar dois eventos: OnDragDrop e OnDragOver com a propriedade DragMode definida como dmAutomatic. Caso contrário, o início da operação de movimentação, o método BeginDrag, deve ser codificado pelo programador.

Para consolidar o material, criaremos o seguinte aplicativo. Coloque um componente Panel no formulário. Defina a propriedade DragMode do Object Inspector como dmAutomatic. Selecione o objeto de formulário e use o Object Inspector para criar os seguintes eventos:

Procedimento TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); comece se Source = Panel1 então Aceitar:= Verdadeiro senão Aceitar:= Falso; fim; procedimento TForm1.FormDragDrop(Sender, Source: TObject; X, Y: Integer); beginPanel1.Esquerda:=X; Panel1.Top:=Y; fim;

Agora, executando a aplicação e pressionando o botão do mouse sobre o painel, podemos mover o objeto painel pelo formulário.

Conclusão: conhecemos a tecnologia arraste e solte(arraste e solte) e usei na prática.

As técnicas de arrastar e soltar evoluíram ao longo de muitos anos. Não surpreendentemente, com o aumento do número de programadores desenvolvendo plugins de código aberto (por exemplo, para jQuery), métodos antigos estão sendo revividos. A biblioteca JavaScript é altamente adaptável e oferece muitas melhorias nesta era da tecnologia da web.

Neste tutorial, faremos um script que podemos usar para criar retângulos dinâmicos de arrastar e soltar em nosso site. O processo é controlado por jQuery. Esses scripts economizam tempo fornecendo funcionalidades prontas! E a biblioteca de arrastar e soltar pode ser usada em outros projetos.

Nós preparamos o conteúdo

Em primeiro lugar, prepararemos um pequeno site para o projeto. Na pasta do projeto, você precisa criar dois diretórios com nomes dignos de nota "js" E "css" e um arquivo vazio index.html . O código será muito simples para que haja uma ideia clara do trabalho e haja um ponto para desenvolvimento posterior.

Abaixo está o código para o nosso arquivo HTML. No capítulo cabeça nós incluímos 3 scripts. O script jQuery principal será carregado do servidor do Google Code. nosso arquivo style.css também está incluído, que contém as principais propriedades para formar aparência nosso documento.

arraste-me

Sim Sim. Exatamente eu.

Eu também posso ser arrastado

( zIndex: 200, opacidade: .9 )

P.S. Você pode me deixar em qualquer lugar!

Dentro de uma seção corpo apenas dois quarteirões div, que contém ambos os retângulos. O código é bastante simples e compreensível. Cabeçalhos com classes são colocados dentro de cada retângulo. manipulador E manipulador2. Isso é importante porque cada retângulo se comporta de maneira diferente ao arrastar.


Instalando o CSS

O código HTML é muito simples. Se você entender a marcação básica, os estilos CSS também não serão difíceis. Ele define principalmente margens, preenchimento e cores.

Corpo,html ( font-family:Calibri, sans-serif; background:#eaf3fb; font-size:12px; height:1000px; line-height:18px; ) p ( height:30px; )

Seletores corpo, html usado apenas para a página de demonstração. E todo o conteúdo é colocado em dois retângulos arrastáveis.

Dv1 (largura:200px; cor de fundo:#eff7ff; borda:1px sólido #96c2f1; posição:absoluto; esquerda:100px; superior:100px;) .dv1 h2 (cor de fundo:#b2d3f5; preenchimento:5px; fonte- família:Georgia, "Times New Roman", Times, serif; tamanho da fonte:1,0em; transformação do texto:maiúsculas; peso da fonte:negrito; cor:#3a424a; margem:1px; cursor:move; ) .dv1 div ( padding:5px; margin-bottom:10px; ) .dv2 ( background-color:#f6ebfb; border:1px solid #a36fde; width:550px; position:absolute; cursor:move; left:400px; top:230px; ) .dv2 h2 ( cor de fundo:#eacfe9; espaçamento entre letras:-0,09em; tamanho da fonte:1,8em; espessura da fonte: negrito; preenchimento:15px; margem:1px; cor:#241f24; cursor:mover; ) .dv2 .content2 (preenchimento:5px; margem inferior:10px;)

Para as classes .dv1 e .dv2, usamos posicionamento absoluto. Isso não é necessário e provavelmente não é o mais A melhor maneira para posicionar retângulos arrastáveis. No entanto, para o nosso exemplo, esse posicionamento faz sentido, pois cada vez que a página é atualizada, os retângulos são definidos em determinados locais.

Além disso, fontes e cores são diferentes para retângulos para facilitar a visualização da diferença.

Caso contrário, os títulos e o conteúdo dos blocos são quase idênticos. Se você for copiar estilos em seu projeto, altere os nomes antes de executá-los. Em alguns casos, fará mais sentido usar IDs em vez de classes, como ao usar uma técnica de arrastar e soltar para um bloco específico.

Analisando JavaScript

Os dois arquivos JavaScript contêm todo o código necessário para fazê-lo funcionar. Iremos pular os detalhes do trabalho com jQuery, pois está fora do escopo deste tutorial. Vamos prestar atenção ao arquivo jquery.dragndrop.js.

A linha 22 é a definição da função Arrasta.

$.fn.Drags = function(opts) ( var ps = $.extend(( zIndex: 20, opacity: .7, handler: null, onMove: function() ( ), onDrop: function() ( ) ), opta );

Isso define a variável de retorno e os dados de inicialização para Arrasta. Este método é muito utilizado quando se trabalha com jQuery para passar opções para outras funções. Dentro, definimos variáveis ​​para todas as opções disponíveis para os retângulos arrastáveis.


O trecho de código a seguir inclui manipuladores de eventos para a variável arraste e solte. Ambos os eventos arrastar E derrubar funções de chamada com a passagem de parâmetros de evento para elas. Esses eventos ocorrem quando você pressiona o botão do mouse para arrastar um objeto e soltá-lo.

Var dragndrop = ( arraste: function(e) ( var dragData = e.data.dragData; dragData.target.css(( esquerda: dragData.left + e.pageX - dragData.offLeft, superior: dragData.top + e.pageY - dragData.offTop )); dragData.handler.css(( cursor: "move" )); dragData.target.css (( cursor: "move" )); dragData.onMove(e); ), drop: function( e) ( var dragData = e.data.dragData; dragData.target.css(dragData.oldCss); //.css(( "opacity": "" )); dragData.handler.css("cursor", dragData. oldCss.cursor); dragData.onDrop(e); $().unbind("mousemove", dragndrop.drag) .unbind("mouseup", dragndrop.drop); ) )

Nossas funções manipulam o posicionamento CSS de cada objeto. Se você alterar o posicionamento absoluto de seus objetos, isso não afetará o funcionamento do seu código, porque toda função JavaScript altera qualquer estilo definido para o objeto.

No restante do código, o manipulador é verificado e outros estilos são alterados cosmeticamente. Aqui você pode adicionar uma alteração na transparência, fonte e cor ou adicionar novos parágrafos.

Funções Arrastar/Soltar

O segundo arquivo fn.js contém um código muito simples. Nós estamos esperando carga máxima document, após o qual chamamos nossas funções. Duas instâncias de função são definidas Arrasta, que foi tratado anteriormente.

Temos dois blocos flutuantes com as classes .dv1 e .dv2 . Se você precisar deixar um bloco flutuante, basta remover a segunda parte do código. Adicionar outro bloco flutuante também é fácil. Você só precisa adicionar uma nova função neste arquivo.

O primeiro passo é definir as opções ao chamar a função. Certifique-se de definir o nome do manipulador. Com ele, dizemos ao jQuery qual manipulador usar quando o botão do mouse for pressionado em uma determinada área do documento. O nome do manipulador pode ser uma classe ou um atributo de ID.

Nossa primeira função tem dois manipuladores de eventos Em movimento E onDrop. Ambos chamam novas funções que são passadas para o evento atual como variáveis. É aqui que o código HTML no retângulo é manipulado para atualizar a cada movimento. Este é um ótimo efeito para demonstrar como você pode controlar o processo com eventos jQuery simples.

Na segunda função, usamos os parâmetros z-Index e opacity. Posso adicionar outras propriedades CSS também? mas isso exigiria reescrever o código JavaScript para validar as instalações. Por exemplo, você pode passar um estilo de fonte ou valores diferentes para a altura e largura do retângulo flutuante - um truque muito interessante!

Conclusão

Como resultado de um pequeno trabalho, temos à nossa disposição uma interface maravilhosa com função de arrastar e soltar. jQuery oferece enormes benefícios para desenvolvedores que estão ansiosos para usar as formas antigas em seus projetos.

Como resultado, não apenas obtivemos funções de manipulador de eventos, mas também podemos passar novas variáveis ​​para blocos arrastáveis. Isso abre novas possibilidades de criatividade. A demonstração da lição contém apenas um esboço do que pode ser feito com a ajuda desse código.

Portanto, verifique a documentação do jQuery para usar as funções da biblioteca.

Para a biblioteca VCL, a Borland implementou sua própria versão da interface Drag&Drop (traduzida como "drag"). Esta interface é interna - você pode enviar e receber qualquer controle Delphi dentro do formulário "(exceto o próprio formulário). É implementado sem usar as funções correspondentes da API do Windows - elas devem ser usadas ao organizar a comunicação com outras tarefas arrastando e soltando .

Pressionando o botão esquerdo do mouse sobre o controle, podemos "arrastá-lo" para qualquer outro elemento. Do ponto de vista do programador, isso significa que certos eventos são gerados nos momentos de arrastar e soltar a tecla, que transmitem todas as informações necessárias - um ponteiro para o objeto arrastado, as coordenadas atuais do cursor, etc. O receptor do evento é o elemento no qual o cursor está localizado atualmente. O manipulador de tal evento deve informar ao sistema se o controle fornecido aceita o "envio" ou não. Quando o botão é liberado no controle do receptor, mais um ou dois eventos são disparados, dependendo da prontidão do receptor.

CancelarArrastar Cancela a operação atual de arrastar e soltar ou arrastar e encaixar.

Função FindDragTarget (const Pos: TPoint ;AllowDisabled: Boolean ): TControl ;

A função retorna um objeto da classe base Tcontrol , que se refere à posição da tela com as coordenadas especificadas pelo parâmetro Pos. Esta função é usada para determinar o destinatário potencial de uma operação de arrastar e soltar ou arrastar e encaixar. Se não existir nenhum controle de janela para a posição especificada, a função retornará nada . O parâmetro AllowDisabled determina se os objetos desativados serão levados em consideração.

Function IsDragObject(Sender: TObject ): Boolean ;

A função determina se o objeto especificado no parâmetro Sender é descendente da classe TDragObject . Essa função pode ser usada como o parâmetro Source nos manipuladores de eventos OnDragOver e OnDockOver para determinar se o objeto arrastado será aceito. Também funciona IsDragObjectpode ser usado como o parâmetro Source nos manipuladores de eventos OnDragDrop e OnDockDrop para interpretar corretamente o objeto arrastado.

DragMode, propriedades DragCursor, métodos BeginDrag, OnDragOver, OnDragDrop, OnEndDrag, OnStartDrag, parâmetro Accept

O processo de arrastar informações de um objeto para outro com o mouse é amplamente utilizado no Widows.Você pode mover arquivos entre pastas, mover as próprias pastas e muito mais.

Todas as propriedades, métodos e eventos associados ao processo de arrastar e soltar são definidos na classe TControl, que é a mãe de todos os componentes visuais do Delphi. Portanto, são comuns a todos os componentes.

O início do arrasto é determinado pela propriedade DragMode, que pode ser definida em tempo de design ou programaticamente igual a dmManual ou dmAutomatic. O valor de dmAutomatic (automático) determina o início automático do processo de arrastar quando o usuário clica com o botão do mouse sobre o componente. No entanto, neste caso, o evento OnMouseDown associado ao usuário pressionando o botão do mouse não ocorre para este componente.

A interface para transferir e receber componentes surgiu há muito tempo. Ele fornece interação entre dois controles durante a execução do aplicativo. Neste caso, qualquer operação necessária pode ser executada. Apesar da simplicidade de implementação e da idade de desenvolvimento, muitos programadores (principalmente iniciantes) consideram esse mecanismo obscuro e exótico. No entanto, usar arrastar e soltar pode ser muito útil e fácil de implementar. Agora vamos verificar isso.

Para que o mecanismo funcione, dois controles devem ser configurados de acordo. Um deve ser a fonte (Source), o segundo - o receptor (Target). Nesse caso, a fonte não se move para lugar nenhum, apenas fica registrada como tal no mecanismo.

Acredite, é fácil converter as coordenadas X,Y passadas nos parâmetros dos eventos OnDragOver e OnDragDrop para formar coordenadas.

Trabalhe com as propriedades Left e Top do componente sobre o qual o cursor está passando. Vou dar um exemplo simples. Coloque um componente Memo no formulário e defina sua propriedade Align como alTop. Coloque um painel no formulário, defina também a propriedade Align como alTop e defina a propriedade Height com um valor pequeno, digamos 6 ou 7 pixels. Defina DragMode como dmAutomatica e DragCursor como crVSplit. Coloque outro componente Memo e defina Align para alClient. Selecione os dois Memos ao mesmo tempo, no painel, e crie um manipulador de evento OnDragOver comum conforme mostrado abaixo:

Recentemente tive a ideia de desenvolver um jogo para Android. Para começar, decidi escrever xadrez. pensei tecnologia Arrastar e soltar perfeito para implementar o mecanismo para mover formas. Para os não iniciados, observo que o método de arrastar e soltar é na possibilidade de arrastar alguns objetos gráficos sobre outros e realizar uma ou outra ação após soltá-los. O exemplo mais simples é remover um atalho da área de trabalho do PC arrastando-o para a lixeira. Ao "jogar" o rótulo no lixo, informamos ao sistema que queremos fazer com que esses dois objetos interajam. O sistema recebe nosso sinal e decide qual ação deve tomar. Arrastar e soltar tornou-se difundido devido à sua clareza intuitiva. Essa abordagem é apoiada por nossa experiência de interação com objetos do mundo real e funciona muito bem em um ambiente virtual. Já no xadrez, através do drag and drop fica tecnologicamente mais fácil determinar a célula onde o usuário arrastou a peça, já que não é necessário calcular o número da célula a partir das coordenadas do ponto de largada. Este trabalho será assumido pela máquina virtual.

Finalidades do uso da tecnologia Drag n Drop

Usar a tecnologia de arrastar e soltar me permite resolver três problemas com pouco sangue:

  1. Visualização do movimento. Quando o usuário toca em uma forma e começa a movê-la pela tela, a forma é substituída por um desenho menor. Assim, o usuário entende que a figura é capturada.
  2. Limitei a área de movimento da figura às dimensões do tabuleiro.
  3. Caso o usuário solte a forma no local errado, ela deverá retornar à sua posição original.

As tarefas estão definidas, vamos começar sua implementação.

Substituir ImageView ao tocar

Todas as minhas formas são objetos ImageView. Infelizmente, descobriu-se que a implementação de Drag & Drop no Android não permite "diretamente da caixa" substituir a imagem de um objeto quando ele é tocado. No entanto, esta tarefa é bastante solucionável por meio da API. Precisamos executar uma série de etapas simples:

  1. Crie um objeto DragShadowBuilder.
  2. Chame o método startDrag.
  3. Oculte nosso ImageView que exibe a forma chamando o método setVisibility com o parâmetro View.INVISIBLE. Como resultado, apenas o objeto DragShadowBuilder permanecerá na tela, o que sinalizará ao usuário que a forma foi capturada.

Essas ações devem ser implementadas no manipulador OnTouchListner do objeto ImageView. Para fazer isso, vamos sobrescrever o método onTouch:

@Override public boolean onTouch(View view, MotionEvent motionEvent) ( if (motionEvent. getAction() == MotionEvent. ACTION_DOWN) ( ClipData clipData= ClipData. newPlainText("" , "" ) ; View. DragShadowBuilder dsb= new View. DragShadowBuilder (view) ;view.startDrag(clipData, dsb, view, 0 ) ;view.setVisibility(View.INVISIBLE) ; return true ; ) else ( return false ; ) )

Tudo é muito simples. Então, com a substituição da imagem calculada, vamos para a próxima tarefa.

Limitando a área de arrastar para a função arrastar e soltar

Restringir a área de arrasto está relacionado a um problema. O fato é que se você soltar a forma fora do quadro, o evento drop não acontecerá, pois o usuário soltou o objeto em um local vazio, e o objeto não tem nada com o que interagir. Como resultado, a figura não retornará ao seu estado original e permanecerá oculta para sempre. Passei muito tempo lendo a documentação, mas não encontrei uma forma de limitar a área de arrasto dos objetos. A revelação veio de repente. Não preciso limitar a área de jeito nenhum, preciso saber se o usuário liberou a figura corretamente ou não.

Determinando a liberação correta
Encontrei respostas para minhas perguntas na seção "manipulação de eventos de finalização de arrastar" no site de desenvolvedores do Android. Aqui estão alguns pontos-chave:

  1. Quando o usuário termina de arrastar, o evento ACTION_DRAG_ENDED é acionado no manipulador DragListeners.
  2. No DragListener, você pode obter informações mais detalhadas sobre a operação de arrastar chamando o método DragEvent.getResult().
  3. Se o DragListener retornar true em resposta a um evento ACTION_DROP, a chamada getResult também retornará true, caso contrário, retornará false.

Portanto, preciso capturar o evento ACTION_DRAG_ENDED e chamar o método getResult. Se retornar falso, o usuário arrastou a forma para fora do quadro e preciso tornar o ImageView visível.

@Override public boolean onDrag(View view, DragEvent dragEvent) ( int dragAction= dragEvent. getAction() ; View dragView= (View) dragEvent. getLocalState() ; if (dragAction== DragEvent. ACTION_DRAG_EXITED) ( containsDragable= false ; ) else if (dragAction== DragEvent. ACTION_DRAG_ENTERED) ( containsDragable= true ; ) else if (dragAction== DragEvent. ACTION_DRAG_ENDED) ( if (dropEventNotHandled(dragEvent) ) ( dragView. setVisibility(View. VISIBLE) ; ) ) else if (dragAction= = DragEvent. ACTION_DROP& amp;& amp; containsDragable) ( checkForValidMove((ChessBoardSquareLayoutView) view, dragView) ; dragView. setVisibility(View. VISIBLE) ; ) return true ; ) private boolean dropEventNotHandled(DragEvent dragEvent) ( return ! dragEvent. getResult( ) ; )

Agora o usuário pode liberar a figura em qualquer lugar e nada de terrível acontecerá.

Determinação dos movimentos permitidos

A última parte do artigo é dedicada a verificar a validade da jogada que o usuário está tentando fazer. Antes de discutir este tópico em detalhes, farei uma pequena observação explicando a estrutura do meu aplicativo. O tabuleiro de damas é representado como um TableLayout e cada célula é descendente de um LinearLayout e tem um OnDragListener.

Além disso, cada OnDragListener refere-se a um objeto "mediador", que cuida da interação dos objetos do jogo e lembra a posição da célula atual.

Quando o usuário arrasta uma forma sobre uma célula, as seguintes ações são possíveis:

  1. Usando o evento ACTION_DRAG_ENTERED para definir a variável 'containsDraggable' como verdadeira.
  2. Usando o evento ACTION_DRAG_EXITED para definir a variável 'containsDraggable' como falsa.
  3. Usando o evento ACTION_DROP para consultar o middleware se uma forma pode ser colocada nesta célula.

Abaixo está o código que implementa a lógica descrita

@Override public boolean onDrag(View view, DragEvent dragEvent) ( int dragAction= dragEvent. getAction() ; View dragView= (View) dragEvent. getLocalState() ; if (dragAction== DragEvent. ACTION_DRAG_EXITED) ( containsDragable= false ; ) else if (dragAction== DragEvent. ACTION_DRAG_ENTERED) ( containsDragable= true ; ) else if (dragAction== DragEvent. ACTION_DRAG_ENDED) ( if (dropEventNotHandled(dragEvent) ) ( dragView. setVisibility(View. VISIBLE) ; ) ) else if (dragAction= = DragEvent.ACTION_DROP& amp;& amp; containsDragable) ( checkForValidMove((ChessBoardSquareLayoutView) view, dragView) ; dragView. setVisibility(View. VISIBLE) ; ) return true ; )

Como você pode ver, independentemente de o movimento ser válido ou não, o ImageView é definido como o estado visível. Eu queria que o usuário visse a forma se mover. Anteriormente, mencionei que a célula é filha de LayoutView. Isso é feito para facilitar a movimentação do ImageView de uma célula para outra. Abaixo está o código do método checkForValidMove, que mostra como o ImageView é movido.

private void checkForValidMove(ChessBoardSquareLayoutView view, View dragView) ( if (mediator. isValidMove(view) ) ( ViewGroup owner= (ViewGroup) dragView. getParent() ; owner. removeView(dragView) ; view. addView(dragView) ; view. setGravity (Gravity.CENTER) ;view.showAsLanded() ;mediator.handleMove(view) ; ) )

Espero que este artigo ajude você a desenvolver seus próprios projetos.


Principal