PageSourceSearch

https://heavenbrook.com/js/script.js?v=2.0

js heavenbrook.com collected 2026-10-02 11:06:30 UTC 3,265 bytes, 103 lines download raw bytes

1document.addEventListener('DOMContentLoaded', () => {
2    // Current Year Update
3    const yearSpan = document.getElementById('year');
4    if (yearSpan) {
5        yearSpan.textContent = new Date().getFullYear();
6    }
7
8    // Navbar Scroll Effect
9    const navbar = document.getElementById('navbar');
10    window.addEventListener('scroll', () => {
11        if (window.scrollY > 50) {
12            navbar.classList.add('scrolled');
13        } else {
14            navbar.classList.remove('scrolled');
15        }
16    });
17
18    // Mobile Menu Toggle
19    const mobileMenu = document.getElementById('mobile-menu');
20    const navMenu = document.querySelector('.nav-menu');
21    const navLinks = document.querySelectorAll('.nav-link');
22
23    mobileMenu.addEventListener('click', () => {
24        mobileMenu.classList.toggle('active');
25        navMenu.classList.toggle('active');
26    });
27
28    navLinks.forEach(link => {
29        link.addEventListener('click', () => {
30            mobileMenu.classList.remove('active');
31            navMenu.classList.remove('active');
32        });
33    });
34
35    // Active Link Highlighting
36    const sections = document.querySelectorAll('section, header');
37    
38    window.addEventListener('scroll', () => {
39        let current = '';
40        sections.forEach(section => {
41            const sectionTop = section.offsetTop;
42            const sectionHeight = section.clientHeight;
43            if (scrollY >= (sectionTop - 200)) {
44                current = section.getAttribute('id');
45            }
46        });
47
48        navLinks.forEach(link => {
49            link.classList.remove('active');
50            if (link.getAttribute('href').includes(current)) {
51                link.classList.add('active');
52            }
53        });
54    });
55
56    // Scroll Reveal Animation (Intersection Observer)
57    const revealElements = document.querySelectorAll('.scroll-reveal');
58    
59    const revealOptions = {
60        threshold: 0.15,
61        rootMargin: "0px 0px -50px 0px"
62    };
63
64    const revealOnScroll = new IntersectionObserver(function(entries, observer) {
65        entries.forEach(entry => {
66            if (!entry.isIntersecting) {
67                return;
68            } else {
69                entry.target.classList.add('visible');
70                observer.unobserve(entry.target);
71            }
72        });
73    }, revealOptions);
74
75    revealElements.forEach(el => {
76        revealOnScroll.observe(el);
77    });
78
79    // Handle Subscribe Form Submission (Dummy Action)
80    const form = document.getElementById('subscribe-form');
81    if (form) {
82        form.addEventListener('submit', (e) => {
83            e.preventDefault();
84            const btn = form.querySelector('.submit-btn');
85            const msg = form.querySelector('.success-msg');
86            const input = form.querySelector('.form-input');
87            
88            btn.textContent = 'Subscribing...';
89            btn.disabled = true;
90
91            setTimeout(() => {
92                btn.textContent = 'Subscribe';
93                btn.disabled = false;
94                input.value = '';
95                msg.style.display = 'block';
96                
97                setTimeout(() => {
98                    msg.style.display = 'none';
99                }, 4000);
100            }, 1000);
101        });
102    }
103});

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.