#182 - Disable Animations Using cookies v0.1

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

Voir la démo

<!-- 💙 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!

Création du scénario Make.com

1. Téléchargez le modèle JSON ci-dessous pour commencer.

2. Naviguez jusqu'à Make.com et créez un nouveau scénario...

3. Cliquez sur la petite boîte avec trois points, puis sur Import Blueprint...

4. Téléchargez votre fichier et voilà ! Vous êtes prêt à relier vos propres comptes.

Besoin d'aide avec ce MemberScript ?

Tous les clients de Memberstack peuvent demander de l'aide dans le Slack 2.0. Veuillez noter qu'il ne s'agit pas de fonctionnalités officielles et que le support ne peut être garanti.

Rejoignez le Slack 2.0
Notes de version
Attributs
Description
Attribut
Aucun élément n'a été trouvé.
Guides / Tutoriels
Aucun élément n'a été trouvé.
Tutoriel
Qu'est-ce que Memberstack ?

Auth & paiements pour les sites Webflow

Ajoutez des logins, des abonnements, du contenu à accès limité, et plus encore à votre site Webflow - facile et entièrement personnalisable.

En savoir plus

"Nous utilisons Memberstack depuis longtemps et il nous a aidé à réaliser des choses que nous n'aurions jamais imaginées avec Webflow. Il nous a aidé à réaliser des choses que nous n'aurions jamais cru possibles en utilisant Webflow. Il nous a permis de construire des plateformes avec beaucoup de profondeur et de fonctionnalité et l'équipe derrière lui a toujours été super utile et réceptif à la rétroaction"

Jamie Debnam
39 Numérique

"J'ai construit un site d'adhésion avec Memberstack et Jetboost pour un client. On a l'impression de construire quelque chose de magique avec ces outils. J'ai travaillé dans une agence où certaines de ces applications ont été codées à partir de zéro, je comprends enfin l'engouement suscité par ces outils. C'est beaucoup plus rapide et beaucoup moins cher."

Félix Meens
Studio Webflix

"L'un des meilleurs produits pour lancer un site d'adhésion - J'aime la facilité d'utilisation de Memberstack. J'ai pu mettre en place mon site d'adhésion en l'espace d'une journée.. Il n'y a rien de plus facile. Il fournit également les fonctionnalités dont j'ai besoin pour rendre l'expérience de l'utilisateur plus personnalisée."

Eric McQuesten
Nerds des technologies de la santé
Off World Depot

"Mon entreprise ne serait pas ce qu'elle est sans Memberstack. Si vous pensez que 30 $/mois c'est cher, essayez d'engager un développeur pour intégrer des recommandations personnalisées à votre site pour ce prix-là. Un ensemble d'outils incroyablement flexibles pour ceux qui sont prêts à faire quelques efforts minimes pour regarder leur documentation bien faite."

Riley Brown
Off World Depot

"La communauté Slack est l'une des plus actives que j'ai vues et les autres clients sont prêts à intervenir pour répondre aux questions et proposer des solutions. J'ai effectué des évaluations approfondies d'outils alternatifs et nous revenons toujours à Memberstack - gagnez du temps et tentez votre chance."

Abbey Burtis
Nerds des technologies de la santé
Slack

Besoin d'aide avec ce MemberScript ? Rejoignez notre communauté Slack !

Rejoignez le Slack de la communauté Memberstack et posez vos questions ! Attendez-vous à une réponse rapide d'un membre de l'équipe, d'un expert Memberstack ou d'un autre membre de la communauté.

Rejoignez notre Slack