SW Core
SW Core / JavaScript / Arrastar (Draggable)

Arrastar (Draggable) JavaScript

Deixa qualquer elemento ser arrastado com o mouse ou o dedo — solto, preso dentro da caixa de fora, só na horizontal ou só na vertical, ou pegando por uma alça.

O que é

Serve para coisas que a pessoa arruma com a mão: uma janelinha de ajuda que ela tira da frente, um adesivo sobre uma foto, um marcador numa planta de imóvel, um controle que desliza. Você coloca sw-drag no elemento e ele passa a acompanhar o mouse/dedo. Com mais atributos você limita até onde ele vai (sw-drag-bounds), trava num eixo (sw-drag-axis) ou define por onde se pega (sw-drag-handle).

Precisa do JavaScript do SW Core. Ao ligar, se o elemento não tem posição nenhuma, o script põe position: absolute (se você já deu rel, fix ou abs, ele respeita) e, durante o arrasto, escreve a posição em left/top. Por isso a caixa de fora precisa ter class="rel" (é em relação a ela que ele se posiciona) e uma altura. O cursor vira a "mãozinha" sozinho, o texto dentro não é selecionado sem querer, e no celular a página não rola enquanto você arrasta o elemento.

Quando usar

  • Janelinha flutuante (ajuda, chat, lembrete) que a pessoa tira da frente: sw-drag com alça na barra de título.
  • Montar algo sobre uma imagem (adesivos, marcadores, etiquetas): sw-drag-bounds="parent" para não sair da imagem.
  • Controle que desliza num sentido só: sw-drag-axis="x".
  • Para reordenar uma lista (arrastar item para outra posição) este componente não serve — ele move livremente, não troca itens de lugar.

Comece aqui

  1. 1

    Coloque o SW Core na página.

    <link rel="stylesheet" href="swcore/swcore.min.css">
    
    <!-- fim do body -->
    <script src="swcore/swcore.min.js"></script>
  2. 2

    Uma caixa de fora com rel e altura (aqui, a proporção ar-21-9), e dentro o elemento com sw-drag. Arraste o cartão.

    Arraste-me
    <div class="rel bd r-m ar-21-9">
      <div sw-drag sw-drag-bounds="parent" class="bg-pri p-2 r-m">Arraste-me</div>
    </div>

Todas as variações

Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.

1. Até onde ele pode ir

Sem sw-drag-bounds ele vai para onde você levar, até para fora da caixa. Com "parent" ele para nas bordas da caixa de fora.

Solto
Sem limite — pode sair da caixa
<div class="rel bd r-m ar-21-9">
  <div sw-drag class="bg-sec p-2 r-m">Solto</div>
</div>
Não saio daqui
sw-drag-bounds="parent" — preso na caixa
<div class="rel bd r-m ar-21-9">
  <div sw-drag sw-drag-bounds="parent" class="bg-pri p-2 r-m">Não saio daqui</div>
</div>

2. Num eixo só

sw-drag-axis="x" só anda na horizontal; "y" só na vertical. Combine com sw-drag-bounds="parent" para ele parar nas pontas.

↔ para os lados
sw-drag-axis="x" — só para os lados
<div class="rel bd r-m ar-21-9">
  <div sw-drag sw-drag-axis="x" sw-drag-bounds="parent" class="bg-suc p-2 r-m">↔ para os lados</div>
</div>
↕ sobe e desce
sw-drag-axis="y" — só para cima e para baixo
<div class="rel bd r-m ar-21-9">
  <div sw-drag sw-drag-axis="y" sw-drag-bounds="parent" class="bg-inf p-2 r-m">↕ sobe e desce</div>
</div>

3. Pegando por uma alça

sw-drag-handle recebe um seletor CSS de uma parte de dentro do elemento: só ela arrasta. O resto continua normal — dá para clicar em botões e ler o texto. É o jeito de fazer uma "janelinha" com barra de título.

⠿ Arraste por aqui
Aqui dentro não arrasta.
sw-drag-handle=".alca"
<div class="rel bd r-m ar-21-9">
  <div sw-drag sw-drag-handle=".alca" sw-drag-bounds="parent" class="bg-sur bd r-m">
    <div class="alca bg-pri p-1">⠿ Arraste por aqui</div>
    <div class="p-2">Aqui dentro não arrasta.</div>
  </div>
</div>

Tabela de opções

PalavraO que fazExemplo
Ligar
sw-dragDeixa o elemento arrastável. Sem posição própria, o script o coloca em position: absolute; com rel/fix/abs ele mantém a sua.<div sw-drag>…</div>
Limite — sw-drag-bounds
(nenhum)Vai para onde for levado, sem limite.
parentNão passa das bordas da caixa de fora (que precisa ter rel).sw-drag-bounds="parent"
windowNão passa das bordas da janela (vale também dentro de uma caixa no meio da página).sw-drag-bounds="window"
Eixo — sw-drag-axis
(nenhum)Anda em qualquer direção.
xSó na horizontal.sw-drag-axis="x"
ySó na vertical.sw-drag-axis="y"
Alça — sw-drag-handle
sw-drag-handleSeletor CSS da parte de dentro que serve de alça. Se não achar, o elemento todo arrasta.sw-drag-handle=".barra"
Grafias antigas (ainda aceitas)
swdrag / swdrag-handle / -axis / -boundsMesmo efeito de sw-drag. Prefira sw-drag em código novo.

Receitas prontas — usos reais

Situações que aparecem em quase todo site. Copie a que servir.

Janelinha de ajuda que a pessoa tira da frente Ao vivo
⠿ Precisa de ajuda?
Fale com a gente pelo WhatsApp. Abrir conversa
<div class="rel bd r-m ar-21-9">
  <div sw-drag sw-drag-handle=".janela-barra" sw-drag-bounds="parent" class="bg-sur bd r-m">
    <div class="janela-barra flx j-sb alc gap-3 bg-pri p-1"><span>⠿ Precisa de ajuda?</span></div>
    <div class="p-2 flx f-cl gap-2">
      <span>Fale com a gente pelo WhatsApp.</span>
      <a href="#" sw-btn="suc p">Abrir conversa</a>
    </div>
  </div>
</div>
Controle que desliza e informa a posição Ao vivo
⇆

Arraste o ponto.

<div class="rel bd r-m ar-21-9" id="trilho">
  <div sw-drag sw-drag-axis="x" sw-drag-bounds="parent" id="ponto" class="bg-pri p-2 r-m">⇆</div>
</div>
<p id="saida"></p>

<script>
  const trilho = document.getElementById('trilho');
  const ponto  = document.getElementById('ponto');

  ponto.addEventListener('sw:drag:move', (e) => {
    // e.detail.x / e.detail.y = posição dentro da caixa, em pixels
    const pct = Math.round(e.detail.x / (trilho.offsetWidth - ponto.offsetWidth) * 100);
    document.getElementById('saida').textContent = 'Posição: ' + pct + '%';
  });
</script>
Lembrar onde a pessoa deixou (depois de recarregar) Referência
<div class="rel ar-21-9">
  <div sw-drag sw-drag-bounds="parent" id="lembrete" class="bg-ale p-2 r-m">Não esqueça!</div>
</div>

<script>
  const nota = document.getElementById('lembrete');

  // volta para a posição salva
  const salvo = JSON.parse(localStorage.getItem('lembrete-pos') || 'null');
  if (salvo) { nota.style.left = salvo.x + 'px'; nota.style.top = salvo.y + 'px'; }

  // guarda a posição ao soltar
  nota.addEventListener('sw:drag:end', () => {
    localStorage.setItem('lembrete-pos', JSON.stringify({ x: nota.offsetLeft, y: nota.offsetTop }));
  });
</script>

Eventos

sw:drag:start
A pessoa começou a arrastar.
sw:drag:move
Durante o arrasto, a cada movimento. Traz e.detail.x e e.detail.y (posição em pixels dentro da caixa de fora).
sw:drag:end
A pessoa soltou.
swdrag:start / :move / :end
Os mesmos eventos com o nome antigo (para código antigo).

API (JavaScript)

SW.Drag.initAll(raiz)
Liga os elementos [sw-drag] dentro de raiz. Normalmente não precisa: o SW Core liga sozinho, até os inseridos depois. SWDrag e SW.Mov são o mesmo objeto.

Precisa de quê

  • swcore.min.css e swcore.min.js.
  • Caixa de fora com class="rel" e altura (ex.: ar-21-9, ou altura no CSS da página).

Cuidados — erros comuns

  • Caixa de fora sem rel: o elemento se posiciona em relação a outra coisa da página e "pula" ao começar a arrastar.
  • Caixa de fora sem altura: como o elemento vira absolute, a caixa fica com altura zero e o elemento aparece por cima do que vem depois.
  • Com class="rel" no próprio elemento, ele anda a partir do lugar onde está no texto (não vira absolute). Para posicionar livre dentro da caixa, deixe o elemento sem classe de posição e ponha rel na caixa de fora.
  • Alça com seletor que não existe dentro do elemento (sw-drag-handle=".barra" sem nenhum .barra dentro): o elemento inteiro vira alça e os botões de dentro param de receber clique.
  • Colocar sw-drag num link ou botão: o clique vira arrasto. Arraste o bloco que está em volta dele, usando uma alça.

O que ele não faz

  • Não guarda a posição: ao recarregar, volta ao lugar inicial (veja a receita com localStorage).
  • Não reordena listas nem "solta dentro" de outro elemento (arrastar e soltar em alvo).
  • Não anda pelo teclado — quem não usa mouse ou toque não consegue mover o elemento.