Sortable Vanilla JS
Quando leio no stackoverflow alguém perguntando como se faz algo com Vanilla JS parece que o autor da pergunta está querendo saber sobre algum framework JS mas na verdade é apenas JS puro sem bibliotecas ou frameworks, Vanilla é apenas uma piada da internet e mesmo não gostando do termo vou usar pois parece ranquear bem no google. 😉
O intuito deste artigo é mostrar uma forma relativamente simples de fazer um sortable/reorder de uma lista de elementos arrastando eles com o mouse, procurei manter o código o mais didático o possível.
Bom, vamos lá ! Primeiramente sobre o HTML, se trata basicamente de uma uma lista de elementos que poderão ser reordenados dentro de uma outra div que chamaremos de bloco.
Para que esses elementos possam ser reordenados precisamos aplicar a propriedade “draggable” (arrastável) nos elementos, assim como no código abaixo.
Já no JavaScript precisaremos atrelar alguns eventos para que o sortable funcione, segue o código.
Salvando as coordenadas 🧭
Primeiramente criaremos um evento “ondragleave” no document que salvará as coordenadas X Y no momento em que o mouse for arrastado com algum elemento selecionado, no caso algum dos elementos do HTML acima.
Movendo elementos 🔄
Após termos as coordenadas, precisaremos aplicar dois eventos em todos os elementos que desejamos mover.
O evento aplicado no primeiro laço “ondragstart” é disparado quando o elemento começa a ser movido. Esse evento salvará na variável “selecionado” qual elemento está sendo movido e aplicará alguns estilos CSS para destacar o elemento dos demais (fundo azul e alguns px de margin acima e abaixo).
Já o evento “ondragend” é disparado quando o elemento é solto em alguma posição, neste ponto do código iremos remover os estilos aplicados antes para que o elemento volte a ser igual a todos e iremos zerar a variável global “selecionado” já que não temos mais nenhum selecionado.
Trocando a posição dos elementos
Não basta apenas mover o elemento que está selecionado, precisamos mover os demais elementos para que a ordem de todos seja alterada. 🤔
Para isso aplicamos no bloco o evento “ondragover”, esse evento será disparado quando algum elemento draggable/arrastável for movido no bloco. Neste evento, chamaremos a função “getProximoItem()” o qual buscará qual é o próximo item da posição atual do mouse, e sabendo qual é o próximo item colocaremos o item movido antes deste ! ⤴️
E quando a função não retornar um próximo elemento, saberemos que ele é o último pois não tem um próximo.
Função para identificação do próximo elemento
A função trabalha em torno da iteração de duas lista de elementos, os elementos do nosso bloco (que podem ser movidos) e os elementos que estão na posição atual do cursor obtidos pela função "elementFromPoint(x, y)”.
Quando encontramos um match entre as listas vamos fazer uma condição de retorno bem simples, caso o mouse esteja acima da metade do elemento retornaremos o anterior e caso esteja abaixo retornaremos ele. Isso faz com que um efeito mais fluido seja aplicado na animação de arrastar e soltar.
E por fim um CSS bem simples, apenas para quebrar o galho.
Abaixo temos o resultado final do sortable. 😃👍