Pular para o conteúdo principal

Como Evitar a Atualização da Página ao Arrastar para Baixo no Mobile


 

Como Evitar a Atualização da Página ao Arrastar para Baixo no Mobile

Em muitos navegadores móveis, um gesto de "puxar para baixo" no topo da página pode acionar a funcionalidade de "pull-to-refresh" (atualização da página). Embora útil em alguns cenários, esse comportamento pode ser indesejado em aplicações web que utilizam elementos de toque ou onde a página não deve ser recarregada.

Neste artigo, vamos aprender como desativar essa funcionalidade indesejada sem prejudicar o comportamento natural de rolagem da página.


Por que "Pull-to-Refresh" Pode Ser um Problema?

Em aplicações web móveis, o "pull-to-refresh" pode interferir com gestos de toque personalizados ou causar frustração ao recarregar a página inadvertidamente. Por exemplo:

  • Interfaces que usam gestos para interatividade.
  • Experiências onde o conteúdo é carregado dinamicamente.
  • Cenários onde a atualização da página pode levar à perda de estado ou dados.


A Solução

Podemos usar eventos de toque (touchstart e touchmove) para detectar quando o usuário tenta "puxar para baixo" no topo da página. Nesse caso, podemos prevenir a ação padrão de atualização, garantindo que a rolagem normal continue funcionando.


Código Completo

 
import { ReactNode, useEffect } from "react";

export interface PreventPullToRefreshContainerProps {
  children: ReactNode;
}

const PreventPullToRefreshContainer = ({
  children,
}: PreventPullToRefreshContainerProps) => {
  useEffect(() => {
    let startY: number | null = null; // Para armazenar a posição inicial do toque.

    // verifica se o elemento possui scroll ativo.
    const isScrollable = (element: HTMLElement): boolean => {
      const style = window.getComputedStyle(element);
      const overflowY = style.overflowY;
      const canScroll = overflowY === "auto" || overflowY === "scroll";
      return canScroll && element.scrollHeight > element.clientHeight;
    };
    
    // verifica se o evento pode ser bloqueado no elemento alvo.
    const shouldPreventPullToRefresh = (target: HTMLElement): boolean => {
      let currentElement: HTMLElement | null = target;

      while (currentElement !== null && currentElement !== document.body) {
        if (isScrollable(currentElement)) {
          return false;
        }
        currentElement = currentElement.parentElement;
      }

      return true; 
    };
    
    const onTouchStart = (e: TouchEvent) => {
      // Salva a posição inicial do toque.
      startY = e.touches[0].clientY;
    };

    const onTouchMove = (e: TouchEvent) => {
      if (startY === null) return;

      const currentY = e.touches[0].clientY;
      const isPullingDown = currentY > startY;

      // Previne "pull-to-refresh" somente se no topo e arrastando para baixo.
      if (window.scrollY === 0 && isPullingDown) {
        const target = e.target as HTMLElement;
        if (shouldPreventPullToRefresh(target)) {
          e.preventDefault();
        }
      }
    };

    // Adiciona os event listeners
    document.addEventListener("touchstart", onTouchStart, { passive: true });
    document.addEventListener("touchmove", onTouchMove, { passive: false });

    // Remove os event listeners no cleanup
    return () => {
      document.removeEventListener("touchstart", onTouchStart);
      document.removeEventListener("touchmove", onTouchMove);
    };
  }, []);

  return <div className="touch-pan-x">{children}</div>;
};

export default PreventPullToRefreshContainer;
       
 

Passo a Passo Explicado

  1. Detectar o Início do Toque (touchstart):

    • Armazenamos a posição inicial do toque em startY.
    • Isso nos ajuda a determinar se o movimento subsequente é para baixo.
  2. Interceptar o Movimento (touchmove):

    • Comparamos a posição atual do toque (currentY) com a posição inicial (startY).
    • Prevenimos o comportamento padrão apenas quando:
      • O scroll está no topo da página (window.scrollY === 0).
      • O movimento detectado é para baixo (currentY > startY).
  3. Prevenir Atualização (e.preventDefault()):

    • Usamos e.preventDefault() para bloquear a funcionalidade de "pull-to-refresh".
    • Configuramos o evento touchmove como não-passivo (passive: false), permitindo que o navegador aceite a chamada de preventDefault().
  4. Limpeza:

    • Removemos os event listeners quando o componente é desmontado, garantindo eficiência e evitando vazamentos de memória.

Benefícios do Método

  • Preserva a rolagem natural: O scroll vertical continuará funcionando normalmente, mesmo no topo da página.
  • Bloqueia apenas o "pull-to-refresh": Garante que a página não seja atualizada por acidente.
  • Fácil de implementar: Pode ser encapsulado em um componente reutilizável, como no exemplo acima.

Dicas Adicionais

  • Certifique-se de usar passive: false no evento touchmove para que e.preventDefault() funcione.
  • Teste o comportamento em diferentes navegadores móveis para garantir que funcione conforme esperado.
  • Use esta técnica com moderação e apenas em casos onde "pull-to-refresh" é realmente indesejado.

Conclusão

Ao desativar o "pull-to-refresh" de forma controlada, podemos criar experiências móveis mais previsíveis e intuitivas. Esta solução preserva a rolagem natural da página e previne ações indesejadas, como a atualização acidental da página.

Se você tiver dúvidas ou quiser mais dicas sobre desenvolvimento web, deixe um comentário abaixo! 🚀

Comentários

Postagens mais visitadas deste blog

Como compilar javascript com Sublime Text

Tutorial de como compilar código javascript com o Editor Sublime Text: Primeiro de tudo é necessário baixar e instalar o node js. Agora, no sublime, clique em Tools - Build System - New Build System..., e cole o código abaixo: { "cmd": ["node", "$file"], "selector": "source.js", "working_dir": "${project_path:${folder}}", "path": "C:\\Program Files\\nodejs" } Atenção: Em path, coloque o caminho correto da instalação do nodejs. Usa-se duas barras mesmo, não é erro! Agora tecle Ctrl + S para salvar este arquivo, já será apontado para o diretório correto, basta mudar o nome do arquivo para node. Nome completo do arquivo deverá ser: node.sublime-build. Pronto! Crie um arquivo de teste e vá em Tools - Build System e selecione a opção node . E para compilar tecle Ctrl + B.

Como criar projeto no Laravel especificando a versão do framework

Olá amigos dev's! Este post nos ensina como criar um projeto em um dos frameworks PHP mais utilizados atualmente, o Laravel. A criação é feita via Composer, porém às vezes queremos trabalhar com uma versão específica do framework e se executarmos o comando sem especificar a versão, ele automaticamente instalará a mais recente. Antes de executarmos o comando para criar o projeto, precisamos instalar o framework. Para tal, executamos o seguinte comando: composer global require "laravel/installer" Ao executar o comando acima, o composer irá se encarregar de baixar e instalar os pacotes das dependências do framework. Se for a primeira vez, ele pode demorar alguns minutos! Após finalizado a instalação do Laravel , executamos o comando para criar nosso projeto. Digite: composer create-project --prefer-dist laravel/laravel nome-do-projeto 5.1.* Note que no final do comando está especificado a versão do framework que desejarmos! Referencias:  https://laravel.c...

Traduzindo Aplicação Laravel

Uma dica muito boa para traduzir sua aplicação desenvolvida em PHP no framework Laravel. Primeiro acessamos o link do projeto no Github que contém a biblioteca com mais de 61 idiomas, que é  https://github.com/caouecs/Laravel-lang Há dois modos de fazermos este processo, baixando a biblioteca através do composer ou copiando somente a pasta do idioma que desejamos traduzir. Baixando a biblioteca via Composer: No terminal, digite o comando abaixo e aguarde o fim da instalação: composer require caouecs/laravel-lang Após instalado, a biblioteca ficará no diretório: app\vendor\caouecs. Acessamos esta pasta e dentro da pasta src  teremos as pastas dos respectivos idiomas, basta copiar a pasta desejada e colar em resources\lang. O outro modo é baixarmos o arquivo da biblioteca compactado direto no Github e fazermos o mesmo processo da cópia da pasta do idioma mencionado acima. Feito isto, acessamos o arquivo de configurações em config\app.php , para mudarmos o idioma d...