|
@@ -1,236 +1,230 @@
|
|
/**
|
|
/**
|
|
- * Auto-Hide Navigation Script - jQuery Version
|
|
|
|
- * Smoothly hides navigation when scrolling down and shows it when scrolling up
|
|
|
|
|
|
+ * SRH Auto-Hide Navigation
|
|
|
|
+ * Hides header when scrolling down, shows when scrolling up
|
|
*/
|
|
*/
|
|
|
|
|
|
(function($) {
|
|
(function($) {
|
|
- 'use strict';
|
|
|
|
-
|
|
|
|
- // Configuration
|
|
|
|
- const config = {
|
|
|
|
- scrollThreshold: 100, // Start hiding after this many pixels
|
|
|
|
- mouseRevealZone: 100, // Show header when mouse is within this many pixels from top
|
|
|
|
- animationDuration: 300, // Animation duration in ms
|
|
|
|
- debounceDelay: 10 // Scroll event debounce delay
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // State management
|
|
|
|
- let state = {
|
|
|
|
- lastScrollTop: 0,
|
|
|
|
- isVisible: true,
|
|
|
|
- headerHeight: 0,
|
|
|
|
- ticking: false
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // DOM elements
|
|
|
|
- let $header, $body;
|
|
|
|
-
|
|
|
|
- // Initialize when document is ready
|
|
|
|
- $(document).ready(function() {
|
|
|
|
- init();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- function init() {
|
|
|
|
- // console.log('Auto-hide navigation: jQuery script loaded');
|
|
|
|
-
|
|
|
|
- // Find header elements - Try multiple selectors for Twenty Twenty-Five
|
|
|
|
- $header = $('header').first();
|
|
|
|
- if (!$header.length) {
|
|
|
|
- $header = $('.wp-site-header').first();
|
|
|
|
- }
|
|
|
|
- if (!$header.length) {
|
|
|
|
- $header = $('.wp-block-template-part[data-area="header"]').first();
|
|
|
|
- }
|
|
|
|
- if (!$header.length) {
|
|
|
|
- $header = $('[class*="header"]').first();
|
|
|
|
- }
|
|
|
|
- if (!$header.length) {
|
|
|
|
- $header = $('nav').first();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $body = $('body');
|
|
|
|
-
|
|
|
|
- // console.log('Header element found:', $header[0]);
|
|
|
|
- // console.log('Header length:', $header.length);
|
|
|
|
-
|
|
|
|
- if (!$header.length) {
|
|
|
|
- console.warn('Auto-hide navigation: No header element found');
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Add identifying class for our CSS
|
|
|
|
- $header.addClass('srh-auto-hide-header');
|
|
|
|
-
|
|
|
|
- // Setup
|
|
|
|
- calculateHeaderHeight();
|
|
|
|
- bindEvents();
|
|
|
|
-
|
|
|
|
- // Initial state
|
|
|
|
- updateHeaderState();
|
|
|
|
-
|
|
|
|
- // console.log('Auto-hide navigation: Initialization complete');
|
|
|
|
- // console.log('Header height calculated:', state.headerHeight);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function calculateHeaderHeight() {
|
|
|
|
- if (!$header.length) return;
|
|
|
|
-
|
|
|
|
- state.headerHeight = $header.outerHeight() || 80;
|
|
|
|
- $('html').css('--header-height', state.headerHeight + 'px');
|
|
|
|
-
|
|
|
|
- // console.log('Header height:', state.headerHeight);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function bindEvents() {
|
|
|
|
- // Scroll event with debouncing
|
|
|
|
- $(window).on('scroll', debounce(handleScroll, config.debounceDelay));
|
|
|
|
-
|
|
|
|
- // Resize event
|
|
|
|
- $(window).on('resize', debounce(calculateHeaderHeight, 100));
|
|
|
|
-
|
|
|
|
- // Mouse movement for revealing header
|
|
|
|
- $(document).on('mousemove', handleMouseMove);
|
|
|
|
-
|
|
|
|
- // Keyboard events for accessibility
|
|
|
|
- $(document).on('keydown', handleKeydown);
|
|
|
|
-
|
|
|
|
- // Focus events for accessibility
|
|
|
|
- $header.find('a, button, input, textarea, select, [tabindex]').on('focus', showHeader);
|
|
|
|
-
|
|
|
|
- // Smooth scroll for anchor links
|
|
|
|
- $(document).on('click', 'a[href^="#"]', handleAnchorClick);
|
|
|
|
-
|
|
|
|
- // console.log('Events bound successfully');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function handleScroll() {
|
|
|
|
- if (!state.ticking) {
|
|
|
|
- requestAnimationFrame(updateHeaderState);
|
|
|
|
- state.ticking = true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function updateHeaderState() {
|
|
|
|
- const scrollTop = $(window).scrollTop();
|
|
|
|
-
|
|
|
|
- // Add scrolled class for styling
|
|
|
|
- if (scrollTop > 50) {
|
|
|
|
- $body.addClass('header-offset');
|
|
|
|
- $header.addClass('header-scrolled');
|
|
|
|
- } else {
|
|
|
|
- $body.removeClass('header-offset');
|
|
|
|
- $header.removeClass('header-scrolled');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Hide/show logic
|
|
|
|
- if (scrollTop > config.scrollThreshold) {
|
|
|
|
- if (scrollTop > state.lastScrollTop && state.isVisible) {
|
|
|
|
- // Scrolling down - hide header
|
|
|
|
- hideHeader();
|
|
|
|
- } else if (scrollTop < state.lastScrollTop && !state.isVisible) {
|
|
|
|
- // Scrolling up - show header
|
|
|
|
- showHeader();
|
|
|
|
- }
|
|
|
|
- } else if (!state.isVisible) {
|
|
|
|
- // Near top - always show header
|
|
|
|
- showHeader();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.lastScrollTop = scrollTop;
|
|
|
|
- state.ticking = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function hideHeader() {
|
|
|
|
- if (!state.isVisible) return;
|
|
|
|
-
|
|
|
|
- // console.log('Hiding header');
|
|
|
|
- state.isVisible = false;
|
|
|
|
- $header.removeClass('header-visible').addClass('header-hidden');
|
|
|
|
-
|
|
|
|
- // Dispatch custom event
|
|
|
|
- $(document).trigger('headerHidden', {
|
|
|
|
- headerElement: $header[0],
|
|
|
|
- isVisible: state.isVisible,
|
|
|
|
- scrollTop: state.lastScrollTop
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function showHeader() {
|
|
|
|
- if (state.isVisible) return;
|
|
|
|
-
|
|
|
|
- // console.log('Showing header');
|
|
|
|
- state.isVisible = true;
|
|
|
|
- $header.removeClass('header-hidden').addClass('header-visible');
|
|
|
|
-
|
|
|
|
- // Dispatch custom event
|
|
|
|
- $(document).trigger('headerVisible', {
|
|
|
|
- headerElement: $header[0],
|
|
|
|
- isVisible: state.isVisible,
|
|
|
|
- scrollTop: state.lastScrollTop
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function handleMouseMove(e) {
|
|
|
|
- if (e.clientY < config.mouseRevealZone &&
|
|
|
|
- $(window).scrollTop() > config.scrollThreshold &&
|
|
|
|
- !state.isVisible) {
|
|
|
|
- showHeader();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function handleKeydown(e) {
|
|
|
|
- // Show header on Tab or Escape for accessibility
|
|
|
|
- if (e.key === 'Tab' || e.key === 'Escape') {
|
|
|
|
- showHeader();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function handleAnchorClick(e) {
|
|
|
|
- const $link = $(e.currentTarget);
|
|
|
|
- const targetId = $link.attr('href').substring(1);
|
|
|
|
- const $target = $('#' + targetId);
|
|
|
|
-
|
|
|
|
- if ($target.length) {
|
|
|
|
- e.preventDefault();
|
|
|
|
-
|
|
|
|
- const offsetTop = $target.offset().top - state.headerHeight;
|
|
|
|
-
|
|
|
|
- $('html, body').animate({
|
|
|
|
- scrollTop: offsetTop
|
|
|
|
- }, 600);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function debounce(func, wait) {
|
|
|
|
- let timeout;
|
|
|
|
- return function executedFunction() {
|
|
|
|
- const context = this;
|
|
|
|
- const args = arguments;
|
|
|
|
- const later = function() {
|
|
|
|
- clearTimeout(timeout);
|
|
|
|
- func.apply(context, args);
|
|
|
|
- };
|
|
|
|
- clearTimeout(timeout);
|
|
|
|
- timeout = setTimeout(later, wait);
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Public API
|
|
|
|
- window.SRHNavigation = {
|
|
|
|
- show: showHeader,
|
|
|
|
- hide: hideHeader,
|
|
|
|
- toggle: function() {
|
|
|
|
- state.isVisible ? hideHeader() : showHeader();
|
|
|
|
- },
|
|
|
|
- getState: function() {
|
|
|
|
- return $.extend({}, state);
|
|
|
|
- },
|
|
|
|
- updateConfig: function(newConfig) {
|
|
|
|
- $.extend(config, newConfig);
|
|
|
|
- },
|
|
|
|
- getHeader: function() {
|
|
|
|
- return $header;
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
|
|
+ 'use strict';
|
|
|
|
+
|
|
|
|
+ // Configuration
|
|
|
|
+ const config = {
|
|
|
|
+ scrollThreshold: 100, // Start hiding after this many pixels
|
|
|
|
+ mouseRevealZone: 100, // Show header when mouse is within this many pixels from top
|
|
|
|
+ animationDuration: 300, // Animation duration in ms
|
|
|
|
+ debounceDelay: 10 // Scroll event debounce delay
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // State management
|
|
|
|
+ let state = {
|
|
|
|
+ lastScrollTop: 0,
|
|
|
|
+ isVisible: true,
|
|
|
|
+ headerHeight: 0,
|
|
|
|
+ ticking: false
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // DOM elements
|
|
|
|
+ let $header, $body;
|
|
|
|
+ const headerSelectors = 'header, .srh-auto-hide-header, .wp-site-header, .wp-block-template-part[data-area="header"]';
|
|
|
|
+
|
|
|
|
+ // Initialize when document is ready
|
|
|
|
+ $(document).ready(function() {
|
|
|
|
+ init();
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ function init() {
|
|
|
|
+ // console.log('Auto-hide navigation: jQuery script loaded');
|
|
|
|
+
|
|
|
|
+ // Find header elements - Try multiple selectors for Twenty Twenty-Five
|
|
|
|
+ $header = $(headerSelectors).first();
|
|
|
|
+
|
|
|
|
+ $body = $('body');
|
|
|
|
+
|
|
|
|
+ // console.log('Header element found:', $header[0]);
|
|
|
|
+ // console.log('Header length:', $header.length);
|
|
|
|
+
|
|
|
|
+ if (!$header.length) {
|
|
|
|
+ console.warn('Auto-hide navigation: No header element found');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Add identifying class for our CSS
|
|
|
|
+ $header.addClass('srh-auto-hide-header');
|
|
|
|
+
|
|
|
|
+ // Setup
|
|
|
|
+ calculateHeaderHeight();
|
|
|
|
+ bindEvents();
|
|
|
|
+
|
|
|
|
+ // Initial state
|
|
|
|
+ updateHeaderState();
|
|
|
|
+
|
|
|
|
+ // Wait for any dynamic content to load
|
|
|
|
+ setTimeout(function() {
|
|
|
|
+ state.headerHeight = calculateHeaderHeight();
|
|
|
|
+ $('body').css('--header-height', state.headerHeight + 'px');
|
|
|
|
+ }, 500);
|
|
|
|
+
|
|
|
|
+ // console.log('Auto-hide navigation: Initialization complete');
|
|
|
|
+ // console.log('Header height calculated:', state.headerHeight);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function calculateHeaderHeight() {
|
|
|
|
+ if (!$header.length) return;
|
|
|
|
+
|
|
|
|
+ state.headerHeight = $header.outerHeight() || 80;
|
|
|
|
+ $('html').css('--header-height', state.headerHeight + 'px');
|
|
|
|
+
|
|
|
|
+ // console.log('Header height:', state.headerHeight);
|
|
|
|
+ return state.headerHeight;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function bindEvents() {
|
|
|
|
+ // Scroll event with debouncing
|
|
|
|
+ $(window).on('scroll', debounce(handleScroll, config.debounceDelay));
|
|
|
|
+
|
|
|
|
+ // Resize event
|
|
|
|
+ $(window).on('resize', debounce(calculateHeaderHeight, 100));
|
|
|
|
+
|
|
|
|
+ // Mouse movement for revealing header
|
|
|
|
+ $(document).on('mousemove', handleMouseMove);
|
|
|
|
+
|
|
|
|
+ // Keyboard events for accessibility
|
|
|
|
+ $(document).on('keydown', handleKeydown);
|
|
|
|
+
|
|
|
|
+ // Focus events for accessibility
|
|
|
|
+ $header.find('a, button, input, textarea, select, [tabindex]').on('focus', showHeader);
|
|
|
|
+
|
|
|
|
+ // Smooth scroll for anchor links
|
|
|
|
+ $(document).on('click', 'a[href^="#"]', handleAnchorClick);
|
|
|
|
+
|
|
|
|
+ // console.log('Events bound successfully');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function handleScroll() {
|
|
|
|
+ if (!state.ticking) {
|
|
|
|
+ requestAnimationFrame(updateHeaderState);
|
|
|
|
+ state.ticking = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function updateHeaderState() {
|
|
|
|
+ const scrollTop = $(window).scrollTop();
|
|
|
|
+
|
|
|
|
+ // Add scrolled class for styling
|
|
|
|
+ if (scrollTop > 10) {
|
|
|
|
+ $header.addClass('header-scrolled');
|
|
|
|
+ } else {
|
|
|
|
+ $header.removeClass('header-scrolled');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Hide/show logic
|
|
|
|
+ if (scrollTop > config.scrollThreshold) {
|
|
|
|
+ if (scrollTop > state.lastScrollTop && state.isVisible) {
|
|
|
|
+ // Scrolling down - hide header
|
|
|
|
+ hideHeader();
|
|
|
|
+ } else if (scrollTop < state.lastScrollTop && !state.isVisible) {
|
|
|
|
+ // Scrolling up - show header
|
|
|
|
+ showHeader();
|
|
|
|
+ }
|
|
|
|
+ } else if (!state.isVisible) {
|
|
|
|
+ // Near top - always show header
|
|
|
|
+ showHeader();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ state.lastScrollTop = scrollTop;
|
|
|
|
+ state.ticking = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function hideHeader() {
|
|
|
|
+ if (!state.isVisible) return;
|
|
|
|
+
|
|
|
|
+ // console.log('Hiding header');
|
|
|
|
+ state.isVisible = false;
|
|
|
|
+ $header.removeClass('header-visible').addClass('header-hidden');
|
|
|
|
+
|
|
|
|
+ // Dispatch custom event
|
|
|
|
+ $(document).trigger('headerHidden', {
|
|
|
|
+ headerElement: $header[0],
|
|
|
|
+ isVisible: state.isVisible,
|
|
|
|
+ scrollTop: state.lastScrollTop
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function showHeader() {
|
|
|
|
+ if (state.isVisible) return;
|
|
|
|
+
|
|
|
|
+ // console.log('Showing header');
|
|
|
|
+ state.isVisible = true;
|
|
|
|
+ $header.removeClass('header-hidden').addClass('header-visible');
|
|
|
|
+
|
|
|
|
+ // Dispatch custom event
|
|
|
|
+ $(document).trigger('headerVisible', {
|
|
|
|
+ headerElement: $header[0],
|
|
|
|
+ isVisible: state.isVisible,
|
|
|
|
+ scrollTop: state.lastScrollTop
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function handleMouseMove(e) {
|
|
|
|
+ if (e.clientY < config.mouseRevealZone &&
|
|
|
|
+ $(window).scrollTop() > config.scrollThreshold &&
|
|
|
|
+ !state.isVisible) {
|
|
|
|
+ showHeader();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function handleKeydown(e) {
|
|
|
|
+ // Show header on Tab or Escape for accessibility
|
|
|
|
+ if (e.key === 'Tab' || e.key === 'Escape') {
|
|
|
|
+ showHeader();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function handleAnchorClick(e) {
|
|
|
|
+ const $link = $(e.currentTarget);
|
|
|
|
+ const targetId = $link.attr('href').substring(1);
|
|
|
|
+ const $target = $('#' + targetId);
|
|
|
|
+
|
|
|
|
+ if ($target.length) {
|
|
|
|
+ e.preventDefault();
|
|
|
|
+
|
|
|
|
+ const offsetTop = $target.offset().top - state.headerHeight;
|
|
|
|
+
|
|
|
|
+ $('html, body').animate({
|
|
|
|
+ scrollTop: offsetTop
|
|
|
|
+ }, 600);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function debounce(func, wait) {
|
|
|
|
+ let timeout;
|
|
|
|
+ return function executedFunction() {
|
|
|
|
+ const context = this;
|
|
|
|
+ const args = arguments;
|
|
|
|
+ const later = function() {
|
|
|
|
+ clearTimeout(timeout);
|
|
|
|
+ func.apply(context, args);
|
|
|
|
+ };
|
|
|
|
+ clearTimeout(timeout);
|
|
|
|
+ timeout = setTimeout(later, wait);
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Public API
|
|
|
|
+ window.SRHNavigation = {
|
|
|
|
+ show: showHeader,
|
|
|
|
+ hide: hideHeader,
|
|
|
|
+ toggle: function() {
|
|
|
|
+ state.isVisible ? hideHeader() : showHeader();
|
|
|
|
+ },
|
|
|
|
+ getState: function() {
|
|
|
|
+ return $.extend({}, state);
|
|
|
|
+ },
|
|
|
|
+ updateConfig: function(newConfig) {
|
|
|
|
+ $.extend(config, newConfig);
|
|
|
|
+ },
|
|
|
|
+ getHeader: function() {
|
|
|
|
+ return $header;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
|
|
})(jQuery);
|
|
})(jQuery);
|