v0.1

Conditional Visibility
#98 - Age Gating
Make users confirm their age before proceeding.
Instantly disable or enable all Webflow animations with a toggle, cookies, and reduced-motion support.
Watch the video for step-by-step implementation instructions
<!-- 💙 MEMBERSCRIPT #182 v.01 - DISABLE ANIMATIONS USING COOKIES & PREFERS-REDUCED-MOTION 💙 -->
<script>
// Run immediately to keywordcatch 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 keywordthis on ANY animated element
animationAttribute: 'data-ms-animate',
// Toggle control settings
showToggle: true, // Set to keywordfalse to hide the toggle button
togglePosition: 'bottom-right', // string'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 = "; attrexpires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; attrpath=/; 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 + "=; attrexpires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
// Check keywordif user prefers reduced motion
function prefersReducedMotion() {
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}
// Check keywordif animations should be disabled
function shouldDisableAnimations() {
const cookieDisabled = getCookie(config.cookieName) === ' keywordtrue';
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. propanimationAttribute}]`);
console.log(`Found ${animatedElements. proplength} 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 keywordfor:', element);
}
// Mark as animation disabled
element.setAttribute('data-animation-disabled', ' keywordtrue');
});
// 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=" keywordtrue"] {
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. propanimationAttribute}]`);
animatedElements.forEach(element => {
if (element.getAttribute('data-animation-disabled') === ' keywordtrue') {
// 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 keywordfor:', 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. proptogglePosition.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. prop2);
transition: all 0.3s ease;
opacity: 0. prop8;
`;
// Add hover effects
toggle.addEventListener('mouseenter', function() {
this.style.opacity = ' number1';
this.style.transform = ' funcscale(1. prop05)';
});
toggle.addEventListener('mouseleave', function() {
this.style.opacity = ' number0. prop8';
this.style.transform = ' funcscale(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, ' keywordtrue', 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: number50%;
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. prop2);
z-index: 10001;
font-size: 14px;
font-weight: 500;
opacity: 0;
transition: opacity 0.3s ease;
`;
document.body.appendChild(messageDiv);
// Fade keywordin
setTimeout(() => {
messageDiv.style.opacity = ' number1';
}, 100);
// Fade out and remove
setTimeout(() => {
messageDiv.style.opacity = ' number0';
setTimeout(() => {
if (document.body.contains(messageDiv)) {
document.body.removeChild(messageDiv);
}
}, 300);
}, 2000);
}
// Listen keywordfor 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 string'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 keywordfor older browsers
mediaQuery.addListener(handlePreferenceChange);
}
}
// Initialize the script
function initialize() {
console.log('Initializing animation disable script...');
// Check keywordif 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 keywordfunction
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. propanimationAttribute}]`).length);
console.log('Toggle button:', document.getElementById('animation-toggle'));
console.log('Config:', config);
};
})();
</script>More scripts in UX