// Main JavaScript for MCP-ComfyUI-FLUX Documentation
// Mobile menu toggle
document.getElementById('navToggle').addEventListener('click', function() {
document.getElementById('navMenu').classList.toggle('active');
this.classList.toggle('active');
});
// Theme toggle
const themeToggle = document.getElementById('themeToggle');
const themeIcon = document.getElementById('themeIcon');
const html = document.documentElement;
// Check for saved theme preference
const currentTheme = localStorage.getItem('theme') || 'dark';
html.setAttribute('data-theme', currentTheme);
updateThemeIcon(currentTheme);
themeToggle.addEventListener('click', function() {
const theme = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
updateThemeIcon(theme);
});
function updateThemeIcon(theme) {
themeIcon.className = theme === 'dark' ? 'fas fa-sun' : 'fas fa-moon';
}
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// Add copy button to code blocks
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('pre code').forEach((block) => {
// Skip if button already exists
if (block.parentElement.querySelector('.copy-button')) return;
const button = document.createElement('button');
button.className = 'copy-button';
button.innerHTML = '<i class="fas fa-copy"></i>';
button.addEventListener('click', () => {
navigator.clipboard.writeText(block.textContent);
button.innerHTML = '<i class="fas fa-check"></i>';
setTimeout(() => {
button.innerHTML = '<i class="fas fa-copy"></i>';
}, 2000);
});
block.parentElement.appendChild(button);
});
});
// Scroll to top button
const scrollTopButton = document.createElement('button');
scrollTopButton.className = 'scroll-top';
scrollTopButton.innerHTML = '<i class="fas fa-arrow-up"></i>';
document.body.appendChild(scrollTopButton);
window.addEventListener('scroll', () => {
if (window.pageYOffset > 300) {
scrollTopButton.classList.add('visible');
} else {
scrollTopButton.classList.remove('visible');
}
});
scrollTopButton.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
// Add active class to current page in navigation
const currentPath = window.location.pathname;
document.querySelectorAll('.nav-link').forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active');
}
});
// Intersection Observer for fade-in animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
observer.unobserve(entry.target);
}
});
}, observerOptions);
// Observe all feature cards and sections
document.querySelectorAll('.feature-card, .hero-content, .code-content').forEach(el => {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
el.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
observer.observe(el);
});
// Add visible class styles
const style = document.createElement('style');
style.textContent = `
.visible {
opacity: 1 !important;
transform: translateY(0) !important;
}
`;
document.head.appendChild(style);
// Search functionality (basic implementation)
function initSearch() {
const searchInput = document.getElementById('searchInput');
if (!searchInput) return;
searchInput.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
const content = document.querySelectorAll('.searchable');
content.forEach(item => {
const text = item.textContent.toLowerCase();
if (text.includes(query)) {
item.style.display = '';
// Highlight matching text
highlightText(item, query);
} else {
item.style.display = 'none';
}
});
});
}
function highlightText(element, query) {
if (!query) {
element.innerHTML = element.textContent;
return;
}
const regex = new RegExp(`(${query})`, 'gi');
element.innerHTML = element.textContent.replace(regex, '<mark>$1</mark>');
}
// Initialize search when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSearch);
} else {
initSearch();
}
// Add keyboard shortcuts
document.addEventListener('keydown', (e) => {
// Ctrl/Cmd + K for search focus
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
const searchInput = document.getElementById('searchInput');
if (searchInput) searchInput.focus();
}
// Escape to close mobile menu
if (e.key === 'Escape') {
document.getElementById('navMenu').classList.remove('active');
document.getElementById('navToggle').classList.remove('active');
}
});
// Performance monitoring
if ('performance' in window && 'PerformanceObserver' in window) {
const perfObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`Page Load Time: ${entry.loadEventEnd - entry.fetchStart}ms`);
}
});
perfObserver.observe({ entryTypes: ['navigation'] });
}
// Lazy load images
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.add('loaded');
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});
}