PageSourceSearch

https://bardoarante.com.br/js/optimized.js

js bardoarante.com.br collected 2026-09-26 15:28:07 UTC 8,123 bytes, 228 lines download raw bytes

1// Optimized JavaScript for Fortune Tiger Site
2(function() {
3    'use strict';
4
5    // DOM ready function
6    function domReady(fn) {
7        if (document.readyState === 'loading') {
8            document.addEventListener('DOMContentLoaded', fn);
9        } else {
10            fn();
11        }
12    }
13
14    // Mobile menu toggle
15    function initMobileMenu() {
16        const menuToggle = document.querySelector('.menu-toggle');
17        const navMenu = document.querySelector('.nav-menu');
18        
19        if (menuToggle && navMenu) {
20            menuToggle.addEventListener('click', function() {
21                navMenu.classList.toggle('toggled');
22                const isExpanded = navMenu.classList.contains('toggled');
23                menuToggle.setAttribute('aria-expanded', isExpanded);
24            });
25
26            // Close menu when clicking outside
27            document.addEventListener('click', function(e) {
28                if (!navMenu.contains(e.target) && !menuToggle.contains(e.target)) {
29                    navMenu.classList.remove('toggled');
30                    menuToggle.setAttribute('aria-expanded', 'false');
31                }
32            });
33        }
34    }
35
36    // Search toggle
37    function initSearch() {
38        const searchToggle = document.querySelector('.toggle-search');
39        const searchExpand = document.querySelector('.search-expand');
40        const searchInput = document.querySelector('.search-expand input');
41        
42        if (searchToggle && searchExpand) {
43            searchToggle.addEventListener('click', function() {
44                searchToggle.classList.toggle('active');
45                searchExpand.style.display = searchExpand.style.display === 'block' ? 'none' : 'block';
46                
47                if (searchInput && searchExpand.style.display === 'block') {
48                    setTimeout(() => searchInput.focus(), 100);
49                }
50            });
51
52            // Close search when clicking outside
53            document.addEventListener('click', function(e) {
54                if (!searchToggle.contains(e.target) && !searchExpand.contains(e.target)) {
55                    searchToggle.classList.remove('active');
56                    searchExpand.style.display = 'none';
57                }
58            });
59        }
60    }
61
62    // Smooth scroll to top
63    function initBackToTop() {
64        const backToTop = document.getElementById('back-to-top');
65        
66        if (backToTop) {
67            backToTop.addEventListener('click', function(e) {
68                e.preventDefault();
69                window.scrollTo({
70                    top: 0,
71                    behavior: 'smooth'
72                });
73            });
74
75            // Show/hide back to top button based on scroll position
76            let ticking = false;
77            function updateBackToTop() {
78                if (window.pageYOffset > 300) {
79                    backToTop.style.display = 'block';
80                } else {
81                    backToTop.style.display = 'none';
82                }
83                ticking = false;
84            }
85
86            function requestTick() {
87                if (!ticking) {
88                    requestAnimationFrame(updateBackToTop);
89                    ticking = true;
90                }
91            }
92
93            window.addEventListener('scroll', requestTick);
94        }
95    }
96
97    // Lazy loading for images
98    function initLazyLoading() {
99        if ('IntersectionObserver' in window) {
100            const imageObserver = new IntersectionObserver((entries, observer) => {
101                entries.forEach(entry => {
102                    if (entry.isIntersecting) {
103                        const img = entry.target;
104                        if (img.dataset.src) {
105                            img.src = img.dataset.src;
106                            img.removeAttribute('data-src');
107                            img.classList.remove('lazy');
108                            observer.unobserve(img);
109                        }
110                    }
111                });
112            });
113
114            document.querySelectorAll('img[data-src]').forEach(img => {
115                imageObserver.observe(img);
116            });
117        }
118    }
119
120    // Touch optimizations for mobile
121    function initTouchOptimizations() {
122        // Add touch class to body for touch devices
123        if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
124            document.body.classList.add('touch-device');
125        }
126
127        // Prevent zoom on double tap for iOS
128        let lastTouchEnd = 0;
129        document.addEventListener('touchend', function(event) {
130            const now = (new Date()).getTime();
131            if (now - lastTouchEnd <= 300) {
132                event.preventDefault();
133            }
134            lastTouchEnd = now;
135        }, false);
136    }
137
138    // Performance optimizations
139    function initPerformanceOptimizations() {
140        // Debounce scroll events
141        let scrollTimeout;
142        const originalScroll = window.onscroll;
143        window.onscroll = function() {
144            if (scrollTimeout) {
145                clearTimeout(scrollTimeout);
146            }
147            scrollTimeout = setTimeout(() => {
148                if (originalScroll) originalScroll();
149            }, 16); // ~60fps
150        };
151
152        // Preload critical resources
153        const criticalImages = [
154            'images/fortune-tiger-logo.png',
155            'images/tigre777.webp'
156        ];
157
158        criticalImages.forEach(src => {
159            const link = document.createElement('link');
160            link.rel = 'preload';
161            link.as = 'image';
162            link.href = src;
163            document.head.appendChild(link);
164        });
165    }
166
167    // Accessibility improvements
168    function initAccessibility() {
169        // Skip link functionality
170        const skipLink = document.querySelector('.skip-link');
171        if (skipLink) {
172            skipLink.addEventListener('click', function(e) {
173                e.preventDefault();
174                const target = document.querySelector(this.getAttribute('href'));
175                if (target) {
176                    target.focus();
177                    target.scrollIntoView();
178                }
179            });
180        }
181
182        // Keyboard navigation for mobile menu
183        const navMenu = document.querySelector('.nav-menu');
184        if (navMenu) {
185            const menuItems = navMenu.querySelectorAll('a, button');
186            menuItems.forEach((item, index) => {
187                item.addEventListener('keydown', function(e) {
188                    if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
189                        e.preventDefault();
190                        const nextItem = menuItems[index + 1] || menuItems[0];
191                        nextItem.focus();
192                    } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
193                        e.preventDefault();
194                        const prevItem = menuItems[index - 1] || menuItems[menuItems.length - 1];
195                        prevItem.focus();
196                    }
197                });
198            });
199        }
200    }
201
202    // Initialize all functions when DOM is ready
203    domReady(function() {
204        initMobileMenu();
205        initSearch();
206        initBackToTop();
207        initLazyLoading();
208        initTouchOptimizations();
209        initPerformanceOptimizations();
210        initAccessibility();
211    });
212
213    // Service Worker registration for PWA capabilities
214    if ('serviceWorker' in navigator) {
215        window.addEventListener('load', function() {
216            navigator.serviceWorker.register('/sw.js')
217                .then(function(registration) {
218                    console.log('ServiceWorker registration successful');
219                })
220                .catch(function(err) {
221                    console.log('ServiceWorker registration failed');
222                });
223        });
224    }
225
226})();
227
228

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.