router.js

3.16 KB
31/03/2025 14:23
JS
router.js
// SPA Router Implementation
class Router {
  constructor() {
    this.routes = {};
    this.currentRoute = '';
    this.contentElement = document.querySelector('main');

    // Handle navigation events
    window.addEventListener('popstate', this.handleRoute.bind(this));

    // Handle initial route
    this.handleRoute();
  }

  // Add a new route
  addRoute(path, callback) {
    this.routes[path] = callback;
    return this;
  }

  // Navigate to a specific route
  navigateTo(path) {
    window.history.pushState({}, '', path);
    this.handleRoute();
  }

  // Handle the current route
  handleRoute() {
    const path = window.location.pathname || '/';

    // If route exists, call its callback
    if (this.routes[path]) {
      this.currentRoute = path;
      this.routes[path]();
    } else {
      // Default to home route if not found
      this.navigateTo('/');
    }
  }

  // Update content based on route
  updateContent(content) {
    this.contentElement.innerHTML = content;

    // Reinitialize components for the new content
    this.initComponents();
  }

  // Initialize components after content update
  initComponents() {
    // Re-initialize project filters
    if (document.querySelector('.projects-filter')) {
      initProjectFilters();
    }

    // Re-initialize contact form
    if (document.getElementById('contactForm')) {
      initContactForm();
    }

    // Set active navigation link
    const navLinks = document.querySelectorAll('nav ul li a');
    navLinks.forEach(link => {
      link.classList.remove('active');
      if (link.getAttribute('data-path') === this.currentRoute) {
        link.classList.add('active');
      }
    });
  }
}

// Initialize SPA when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
  // Create router instance
  const router = new Router();

  // Store content sections
  const sections = {};
  document.querySelectorAll('section').forEach(section => {
    sections[section.id] = section.outerHTML;
  });


});

router.addRoute('/about', () => {
  router.updateContent(sections.about);
});

router.addRoute('/skills', () => {
  router.updateContent(sections.skills);
});

router.addRoute('/showcase', () => {
  router.updateContent(sections.showcase);
});

router.addRoute('/projects', () => {
  router.updateContent(sections.projects);
});

router.addRoute('/contact', () => {
  router.updateContent(sections.contact);
});

// Update navigation links for SPA
document.querySelectorAll('nav ul li a').forEach(link => {
  const path = link.getAttribute('href').replace('#', '/');

  // Update href for SPA navigation
  link.setAttribute('data-path', path);

  // Add click event for SPA navigation
  link.addEventListener('click', (e) => {
    e.preventDefault();

    // Navigate to the specified route
    router.navigateTo(path);

    // Scroll to top
    window.scrollTo({
      top: 0,
      behavior: 'smooth'
    });

    // Close mobile menu if open
    const nav = document.querySelector('nav');
    if (nav.classList.contains('active')) {
      nav.classList.remove('active');
      const menuToggleBtn = document.getElementById('menu-toggle-btn');
      menuToggleBtn.innerHTML = '<i class="fas fa-bars"></i>';
    }
  });
});