#182 - Disable Animations Using cookies v0.1

Instantly disable or enable all Webflow animations with a toggle, cookies, and reduced-motion support.

Ver demostración

<!-- 💙 MEMBERSCRIPT #182 v.01 - DISABLE ANIMATIONS USING COOKIES & PREFERS-REDUCED-MOTION 💙 -->
<script>
// Run immediately to catch animations before they start
(function() {
  console.log('Animation Disable Script loaded!');
  
  // Configuration - Customize these values as needed
  const config = {
    // Cookie settings
    cookieName: 'animationsDisabled',
    cookieExpiryDays: 365, // How long to remember the preference
    
    // Universal animation attribute - use this on ANY animated element
    animationAttribute: 'data-ms-animate',
    
    // Toggle control settings
    showToggle: true, // Set to false to hide the toggle button
    togglePosition: 'bottom-right', // 'top-right', 'bottom-right', 'top-left', 'bottom-left'
    toggleText: {
      disable: 'Disable Animations',
      enable: 'Enable Animations'
    }
  };
  
  // Cookie management functions
  function setCookie(name, value, days) {
    let expires = "";
    if (days) {
      const date = new Date();
      date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
      expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "") + expires + "; path=/; SameSite=Lax";
  }
  
  function getCookie(name) {
    const nameEQ = name + "=";
    const ca = document.cookie.split(';');
    for (let i = 0; i < ca.length; i++) {
      let c = ca[i];
      while (c.charAt(0) === ' ') c = c.substring(1, c.length);
      if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
  }
  
  function deleteCookie(name) {
    document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
  }
  
  // Check if user prefers reduced motion
  function prefersReducedMotion() {
    return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  }
  
  // Check if animations should be disabled
  function shouldDisableAnimations() {
    const cookieDisabled = getCookie(config.cookieName) === 'true';
    const systemPrefersReduced = prefersReducedMotion();
    
    console.log('Animation check:', {
      cookieDisabled,
      systemPrefersReduced,
      shouldDisable: cookieDisabled || systemPrefersReduced
    });
    
    return cookieDisabled || systemPrefersReduced;
  }
  
  // Disable animations on page
  function disableAnimations() {
    console.log('Disabling animations...');
    
    // Find all elements with the animation attribute
    const animatedElements = document.querySelectorAll(`[${config.animationAttribute}]`);
    console.log(`Found ${animatedElements.length} animated elements`);
    
    animatedElements.forEach(element => {
      // Remove Webflow animation ID to prevent interactions
      const webflowId = element.getAttribute('data-w-id');
      if (webflowId) {
        element.setAttribute('data-w-id-disabled', webflowId);
        element.removeAttribute('data-w-id');
        console.log('Disabled Webflow animation for:', element);
      }
      
      // Mark as animation disabled
      element.setAttribute('data-animation-disabled', 'true');
    });
    
    // Disable Webflow interactions globally
    if (window.Webflow && window.Webflow.require) {
      try {
        const ix2 = window.Webflow.require('ix2');
        if (ix2 && ix2.store) {
          ix2.store.dispatch({ type: 'ix2/STORE_DISABLE' });
          console.log('Disabled Webflow interactions globally');
        }
      } catch (e) {
        console.log('Could not disable Webflow interactions:', e);
      }
    }
    
    // Override Webflow animation styles
    const style = document.createElement('style');
    style.id = 'webflow-animation-disable';
    style.textContent = `
      [data-animation-disabled="true"] {
        animation: none !important;
        transition: none !important;
        transform: none !important;
        opacity: 1 !important;
        visibility: visible !important;
      }
    `;
    
    if (!document.getElementById('webflow-animation-disable')) {
      document.head.appendChild(style);
    }
    
    console.log('Animations disabled successfully');
  }
  
  // Enable animations on page
  function enableAnimations() {
    console.log('Enabling animations...');
    
    // Find all elements with the animation attribute
    const animatedElements = document.querySelectorAll(`[${config.animationAttribute}]`);
    
    animatedElements.forEach(element => {
      if (element.getAttribute('data-animation-disabled') === 'true') {
        // Restore Webflow animation ID
        const disabledId = element.getAttribute('data-w-id-disabled');
        if (disabledId) {
          element.setAttribute('data-w-id', disabledId);
          element.removeAttribute('data-w-id-disabled');
          console.log('Re-enabled Webflow animation for:', element);
        }
        
        // Remove disabled marker
        element.removeAttribute('data-animation-disabled');
      }
    });
    
    // Re-enable Webflow interactions globally
    if (window.Webflow && window.Webflow.require) {
      try {
        const ix2 = window.Webflow.require('ix2');
        if (ix2 && ix2.store) {
          ix2.store.dispatch({ type: 'ix2/STORE_ENABLE' });
          console.log('Re-enabled Webflow interactions globally');
        }
      } catch (e) {
        console.log('Could not re-enable Webflow interactions:', e);
      }
    }
    
    // Remove override styles
    const style = document.getElementById('webflow-animation-disable');
    if (style) {
      style.remove();
    }
    
    console.log('Animations enabled successfully');
  }
  
  // Create toggle button
  function createToggleButton() {
    if (!config.showToggle) return;
    
    // Double check that body exists
    if (!document.body) {
      console.log('Body not ready, retrying toggle creation...');
      setTimeout(createToggleButton, 100);
      return;
    }
    //CUSTOMIZE THE TOGGLE COLORS
    const toggle = document.createElement('button');
    toggle.id = 'animation-toggle';
    toggle.type = 'button';
    toggle.setAttribute('data-ms-code', 'animation-toggle');
    toggle.style.cssText = `
      position: fixed;
      ${config.togglePosition.includes('top') ? 'top: 20px;' : 'bottom: 20px;'}
      ${config.togglePosition.includes('right') ? 'right: 20px;' : 'left: 20px;'}
      z-index: 10000;
      background: #2d62ff; 
      color: white;
      border: none;
      padding: 10px 15px;
      border-radius: 25px;
      cursor: pointer;
      font-size: 12px;
      font-weight: 500;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
      transition: all 0.3s ease;
      opacity: 0.8;
    `;
    
    // Add hover effects
    toggle.addEventListener('mouseenter', function() {
      this.style.opacity = '1';
      this.style.transform = 'scale(1.05)';
    });
    
    toggle.addEventListener('mouseleave', function() {
      this.style.opacity = '0.8';
      this.style.transform = 'scale(1)';
    });
    
    // Add click handler
    toggle.addEventListener('click', function() {
      console.log('Toggle clicked!');
      const currentlyDisabled = shouldDisableAnimations();
      console.log('Currently disabled:', currentlyDisabled);
      
      if (currentlyDisabled) {
        // Enable animations
        console.log('Enabling animations...');
        deleteCookie(config.cookieName);
        enableAnimations();
        updateToggleButton(false);
        showMessage('Animations enabled', 'success');
      } else {
        // Disable animations
        console.log('Disabling animations...');
        setCookie(config.cookieName, 'true', config.cookieExpiryDays);
        disableAnimations();
        updateToggleButton(true);
        showMessage('Animations disabled', 'info');
      }
    });
    
    document.body.appendChild(toggle);
    updateToggleButton(shouldDisableAnimations());
    
    console.log('Toggle button created');
  }
  
  // Update toggle button text and state
  function updateToggleButton(disabled) {
    const toggle = document.getElementById('animation-toggle');
    if (!toggle) return;
    
    toggle.textContent = disabled ? config.toggleText.enable : config.toggleText.disable;
    toggle.style.background = disabled ? '#28a745' : '#2d62ff';
  }
  
  // Show message to user, CUSTOMIZE THIS
  function showMessage(message, type = 'info') {
    const messageDiv = document.createElement('div');
    messageDiv.className = 'animation-message';
    messageDiv.textContent = message;
    
    const colors = {
      success: '#28a745',
      error: '#dc3545',
      info: '#2d62ff',
      warning: '#ffc107'
    };
    
    messageDiv.style.cssText = `
      position: fixed;
      top: 20px;
      left: 50%;
      transform: translateX(-50%);
      background: ${colors[type] || colors.info};
      color: white;
      padding: 12px 20px;
      border-radius: 25px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
      z-index: 10001;
      font-size: 14px;
      font-weight: 500;
      opacity: 0;
      transition: opacity 0.3s ease;
    `;
    
    document.body.appendChild(messageDiv);
    
    // Fade in
    setTimeout(() => {
      messageDiv.style.opacity = '1';
    }, 100);
    
    // Fade out and remove
    setTimeout(() => {
      messageDiv.style.opacity = '0';
      setTimeout(() => {
        if (document.body.contains(messageDiv)) {
          document.body.removeChild(messageDiv);
        }
      }, 300);
    }, 2000);
  }
  
  // Listen for system preference changes
  function setupPreferenceListener() {
    const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
    
    function handlePreferenceChange(e) {
      console.log('System preference changed:', e.matches);
      
      if (e.matches && !getCookie(config.cookieName)) {
        // User now prefers reduced motion and hasn't manually set a preference
        disableAnimations();
        updateToggleButton(true);
      } else if (!e.matches && !getCookie(config.cookieName)) {
        // User no longer prefers reduced motion and hasn't manually set a preference
        enableAnimations();
        updateToggleButton(false);
      }
    }
    
    // Modern browsers
    if (mediaQuery.addEventListener) {
      mediaQuery.addEventListener('change', handlePreferenceChange);
    } else {
      // Fallback for older browsers
      mediaQuery.addListener(handlePreferenceChange);
    }
  }
  
  // Initialize the script
  function initialize() {
    console.log('Initializing animation disable script...');
    
    // Check if animations should be disabled
    if (shouldDisableAnimations()) {
      disableAnimations();
    }
    
    // Setup preference listener
    setupPreferenceListener();
    
    console.log('Animation disable script initialized successfully');
  }
  
  // Initialize animations immediately
  initialize();
  
  // Create toggle button when body is ready
  function createToggleWhenReady() {
    if (document.body) {
      createToggleButton();
    } else {
      setTimeout(createToggleWhenReady, 10);
    }
  }
  
  // Run when DOM is ready
  document.addEventListener('DOMContentLoaded', function() {
    initialize();
    createToggleWhenReady();
  });
  
  // Debug function
  window.debugAnimationDisable = function() {
    console.log('=== Animation Disable Debug Info ===');
    console.log('Cookie value:', getCookie(config.cookieName));
    console.log('Prefers reduced motion:', prefersReducedMotion());
    console.log('Should disable animations:', shouldDisableAnimations());
    console.log('Animation elements found:', document.querySelectorAll(`[${config.animationAttribute}]`).length);
    console.log('Toggle button:', document.getElementById('animation-toggle'));
    console.log('Config:', config);
  };
})();
</script>

Customer Showcase

Have you used a Memberscript in your project? We’d love to highlight your work and share it with the community!

Creación del escenario Make.com

1. Descargue el proyecto JSON a continuación para empezar.

2. Navegue hasta Make.com y Cree un nuevo escenario...

3. Haga clic en el pequeño cuadro con 3 puntos y luego Importar Blueprint...

4. Sube tu archivo y ¡voilá! Ya está listo para vincular sus propias cuentas.

¿Necesitas ayuda con este MemberScript?

Todos los clientes de Memberstack pueden solicitar asistencia en el Slack 2.0. Tenga en cuenta que no se trata de funciones oficiales y que no se puede garantizar la asistencia.

Únete al Slack 2.0
Notas de la versión
Atributos
Descripción
Atributo
No se han encontrado artículos.
Guías / Tutoriales
No se han encontrado artículos.
Tutorial
¿Qué es Memberstack?

Autenticación y pagos para sitios Webflow

Añada inicios de sesión, suscripciones, contenido cerrado y mucho más a su sitio Webflow: fácil y totalmente personalizable.

Más información

"Hemos estado utilizando Memberstack durante mucho tiempo, y nos ha ayudado a lograr cosas que nunca hubiéramos creído posible usando Webflow. Nos ha permitido construir plataformas con gran profundidad y funcionalidad y el equipo que hay detrás siempre ha sido súper servicial y receptivo a los comentarios"

Jamie Debnam
39 Digital

"He estado construyendo un sitio de membresía con Memberstack y Jetboost para un cliente. Se siente como magia construir con estas herramientas. Como alguien que ha trabajado en una agencia donde algunas de estas aplicaciones fueron codificadas desde cero, finalmente entiendo el bombo ahora. Esto es mucho más rápido y mucho más barato."

Félix Meens
Estudio Webflix

"Uno de los mejores productos para iniciar un sitio de membresía - Me gusta la facilidad de uso de Memberstack. Yo era capaz de mi sitio de membresía en marcha y funcionando dentro de un día. No hay nada más fácil que eso. También proporciona la funcionalidad que necesito para hacer la experiencia del usuario más personalizada."

Eric McQuesten
Nerds de la tecnología sanitaria
Depósito Off World

"Mi negocio no sería lo que es sin Memberstack. Si crees que 30 $/mes es caro, prueba a contratar a un desarrollador para que integre recomendaciones personalizadas en tu sitio por ese precio. Increíblemente flexible conjunto de herramientas para aquellos dispuestos a poner en algunos esfuerzos mínimos para ver su documentación bien elaborado."

Riley Brown
Depósito Off World

"La comunidad de Slack es una de las más activas que he visto y los clientes están dispuestos a responder preguntas y ofrecer soluciones. He realizado evaluaciones en profundidad de herramientas alternativas y siempre volvemos a Memberstack: ahórrate el tiempo y dale una oportunidad"."

Abadía Burtis
Nerds de la tecnología sanitaria
Slack

¿Necesitas ayuda con este MemberScript? ¡Únete a nuestra comunidad Slack!

Únete al Slack de la comunidad Memberstack y ¡pregunta! Espera una respuesta rápida de un miembro del equipo, un experto de Memberstack o un compañero de la comunidad.

Únete a nuestro Slack