// ======================================== // FAQ 페이지 전용 JavaScript // ======================================== document.addEventListener('DOMContentLoaded', function() { initFAQ(); initSearch(); initCategories(); initAnimations(); initEmailForm(); }); // FAQ 기능 초기화 function initFAQ() { const faqItems = document.querySelectorAll('.faq-item'); faqItems.forEach(item => { const question = item.querySelector('.faq-question'); const toggle = item.querySelector('.faq-toggle'); const answer = item.querySelector('.faq-answer'); if (question && toggle && answer) { question.addEventListener('click', () => toggleFAQ(item)); // 키보드 접근성 question.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleFAQ(item); } }); // 포커스 가능하도록 설정 question.setAttribute('tabindex', '0'); question.setAttribute('role', 'button'); question.setAttribute('aria-expanded', 'false'); } }); } // FAQ 아이템 토글 function toggleFAQ(item) { const isActive = item.classList.contains('active'); const answer = item.querySelector('.faq-answer'); const question = item.querySelector('.faq-question'); if (isActive) { // 닫기 item.classList.remove('active'); question.setAttribute('aria-expanded', 'false'); answer.style.maxHeight = '0'; } else { // 다른 모든 FAQ 닫기 (아코디언 효과) document.querySelectorAll('.faq-item.active').forEach(activeItem => { if (activeItem !== item) { activeItem.classList.remove('active'); activeItem.querySelector('.faq-question').setAttribute('aria-expanded', 'false'); activeItem.querySelector('.faq-answer').style.maxHeight = '0'; } }); // 현재 FAQ 열기 item.classList.add('active'); question.setAttribute('aria-expanded', 'true'); // 정확한 높이 계산을 위해 잠시 보이게 한 후 측정 answer.style.maxHeight = 'none'; answer.style.overflow = 'visible'; const height = answer.scrollHeight; answer.style.maxHeight = '0'; answer.style.overflow = 'hidden'; // 애니메이션을 위해 약간의 지연 후 높이 설정 setTimeout(() => { answer.style.maxHeight = (height + 50) + 'px'; }, 10); // 스크롤 애니메이션 setTimeout(() => { item.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }, 100); } } // 검색 기능 초기화 function initSearch() { const searchInput = document.getElementById('faqSearch'); const searchBtn = document.querySelector('.search-btn'); const suggestions = document.getElementById('searchSuggestions'); if (searchInput) { let searchTimeout; searchInput.addEventListener('input', function() { clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { handleSearch(this.value.trim()); updateSearchSuggestions(this.value.trim()); }, 300); }); searchInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') { e.preventDefault(); handleSearch(this.value.trim()); hideSuggestions(); } }); // 검색 버튼 클릭 if (searchBtn) { searchBtn.addEventListener('click', () => { handleSearch(searchInput.value.trim()); hideSuggestions(); }); } // 클릭 외부 영역 시 제안 사항 숨기기 document.addEventListener('click', function(e) { if (!searchInput.contains(e.target) && !suggestions?.contains(e.target)) { hideSuggestions(); } }); } } // 검색 처리 function handleSearch(query) { const faqItems = document.querySelectorAll('.faq-item'); const noResults = document.querySelector('.no-results'); let hasResults = false; if (!query) { // 검색어가 없으면 모든 항목 표시 faqItems.forEach(item => { item.classList.remove('hidden'); clearSearchHighlight(item); }); hideNoResults(); return; } const searchRegex = new RegExp(query, 'gi'); faqItems.forEach(item => { const question = item.querySelector('.faq-question h3'); const answer = item.querySelector('.faq-answer'); const questionText = question.textContent; const answerText = answer.textContent; // 검색어 매칭 확인 const questionMatch = searchRegex.test(questionText); const answerMatch = searchRegex.test(answerText); if (questionMatch || answerMatch) { item.classList.remove('hidden'); hasResults = true; // 검색어 하이라이트 highlightSearchTerm(item, query); // 답변에 매칭되는 경우 자동으로 열기 if (answerMatch && !questionMatch) { toggleFAQ(item); } } else { item.classList.add('hidden'); clearSearchHighlight(item); } }); // 검색 결과가 없는 경우 if (!hasResults) { showNoResults(query); } else { hideNoResults(); } } // 검색어 하이라이트 function highlightSearchTerm(item, term) { const question = item.querySelector('.faq-question h3'); const answer = item.querySelector('.faq-answer'); const escapedTerm = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const highlightRegex = new RegExp(`(${escapedTerm})`, 'gi'); // 질문 하이라이트 const originalQuestionText = question.dataset.originalText || question.textContent; question.dataset.originalText = originalQuestionText; question.innerHTML = originalQuestionText.replace(highlightRegex, '$1'); // 답변 하이라이트 const answerElements = answer.querySelectorAll('p, li'); answerElements.forEach(el => { const originalText = el.dataset.originalText || el.textContent; el.dataset.originalText = originalText; el.innerHTML = originalText.replace(highlightRegex, '$1'); }); } // 검색 하이라이트 제거 function clearSearchHighlight(item) { const question = item.querySelector('.faq-question h3'); const answer = item.querySelector('.faq-answer'); // 질문 하이라이트 제거 if (question.dataset.originalText) { question.textContent = question.dataset.originalText; delete question.dataset.originalText; } // 답변 하이라이트 제거 const answerElements = answer.querySelectorAll('p, li'); answerElements.forEach(el => { if (el.dataset.originalText) { el.textContent = el.dataset.originalText; delete el.dataset.originalText; } }); } // 검색 제안사항 업데이트 function updateSearchSuggestions(query) { const suggestions = document.getElementById('searchSuggestions'); if (!suggestions || !query || query.length < 2) { hideSuggestions(); return; } // 미리 정의된 검색 키워드 const searchKeywords = [ '예약', '취소', '환불', '요금', '가격', '결제', '장비', '모션캡쳐', '시간', '인원', '준비물', '데이터', '파일', '형식', '스트리밍', '버튜버', '주차', '위치', '견학', '투어', '방역', '코로나' ]; const matchingKeywords = searchKeywords.filter(keyword => keyword.includes(query) || query.includes(keyword) ); if (matchingKeywords.length > 0) { suggestions.innerHTML = matchingKeywords .slice(0, 5) .map(keyword => `
${keyword}
` ).join(''); suggestions.classList.add('active'); } else { hideSuggestions(); } } // 제안사항 선택 function selectSuggestion(keyword) { const searchInput = document.getElementById('faqSearch'); if (searchInput) { searchInput.value = keyword; handleSearch(keyword); } hideSuggestions(); } // 제안사항 숨기기 function hideSuggestions() { const suggestions = document.getElementById('searchSuggestions'); if (suggestions) { suggestions.classList.remove('active'); } } // 검색 결과 없음 표시 function showNoResults(query) { const safeQuery = query.replace(/[<>&"]/g, c => ({'<':'<','>':'>','&':'&','"':'"'})[c]); let noResults = document.querySelector('.no-results'); if (!noResults) { noResults = document.createElement('div'); noResults.className = 'no-results'; noResults.innerHTML = `
🔍

검색 결과가 없습니다

"${safeQuery}"와 관련된 질문을 찾을 수 없습니다.

다른 키워드로 검색해보시거나 직접 문의해 주세요.

`; document.querySelector('.faq-list').appendChild(noResults); } else { noResults.querySelector('p strong').textContent = `"${query}"`; } noResults.classList.add('active'); } // 검색 결과 없음 숨기기 function hideNoResults() { const noResults = document.querySelector('.no-results'); if (noResults) { noResults.classList.remove('active'); } } // 카테고리 필터 초기화 function initCategories() { const categoryBtns = document.querySelectorAll('.category-btn'); categoryBtns.forEach(btn => { btn.addEventListener('click', function() { const category = this.dataset.category; // 활성 버튼 업데이트 categoryBtns.forEach(b => b.classList.remove('active')); this.classList.add('active'); // FAQ 필터링 filterByCategory(category); // 검색 초기화 const searchInput = document.getElementById('faqSearch'); if (searchInput) { searchInput.value = ''; } hideSuggestions(); hideNoResults(); }); }); } // 카테고리별 필터링 function filterByCategory(category) { const faqItems = document.querySelectorAll('.faq-item'); faqItems.forEach(item => { // 모든 FAQ 닫기 item.classList.remove('active'); item.querySelector('.faq-answer').style.maxHeight = '0'; item.querySelector('.faq-question').setAttribute('aria-expanded', 'false'); // 검색 하이라이트 제거 clearSearchHighlight(item); if (category === 'all' || item.dataset.category === category) { item.classList.remove('hidden'); } else { item.classList.add('hidden'); } }); // 페이지 상단으로 스크롤 document.querySelector('.faq-list').scrollIntoView({ behavior: 'smooth', block: 'start' }); } // 애니메이션 초기화 function initAnimations() { // Intersection Observer를 사용한 스크롤 애니메이션 const observerOptions = { threshold: 0.1, rootMargin: '50px 0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach((entry, index) => { if (entry.isIntersecting) { setTimeout(() => { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; }, index * 100); observer.unobserve(entry.target); } }); }, observerOptions); // FAQ 아이템들에 초기 스타일 적용 및 관찰 시작 const faqItems = document.querySelectorAll('.faq-item'); faqItems.forEach(item => { item.style.opacity = '0'; item.style.transform = 'translateY(30px)'; item.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)'; observer.observe(item); }); } // URL 해시로 특정 FAQ 열기 function openFAQByHash() { const hash = window.location.hash.substring(1); if (hash) { const faqItem = document.querySelector(`[data-id="${hash}"]`); if (faqItem) { toggleFAQ(faqItem); faqItem.scrollIntoView({ behavior: 'smooth', block: 'center' }); } } } // 페이지 로드 시 해시 확인 window.addEventListener('load', openFAQByHash); // FAQ 공유 기능 (선택사항) function shareFAQ(faqId) { const url = `${window.location.origin}${window.location.pathname}#${faqId}`; if (navigator.share) { navigator.share({ title: 'FAQ - 밍글 스튜디오', url: url }); } else { // 클립보드에 복사 navigator.clipboard.writeText(url).then(() => { if (window.commonUtils && window.commonUtils.showNotification) { window.commonUtils.showNotification('링크가 클립보드에 복사되었습니다.', 'success'); } }); } } // 이메일 폼 초기화 function initEmailForm() { const emailBtn = document.getElementById('showEmailFormFAQ'); const emailForm = document.getElementById('emailFormFAQ'); if (emailBtn && emailForm) { emailBtn.addEventListener('click', function() { if (emailForm.style.display === 'none' || !emailForm.style.display) { emailForm.style.display = 'block'; emailBtn.textContent = '📧 양식 숨기기'; // FAQ 답변 높이 재계산 const faqItem = emailForm.closest('.faq-item'); const answer = faqItem.querySelector('.faq-answer'); if (faqItem.classList.contains('active')) { // 높이 재계산을 위해 잠시 auto로 설정 answer.style.maxHeight = 'none'; const newHeight = answer.scrollHeight; answer.style.maxHeight = (newHeight + 100) + 'px'; // 여유분 추가 } setTimeout(() => { emailForm.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }, 100); } else { emailForm.style.display = 'none'; emailBtn.innerHTML = '📧 이메일 문의하기'; // FAQ 답변 높이 재계산 const faqItem = emailForm.closest('.faq-item'); const answer = faqItem.querySelector('.faq-answer'); if (faqItem.classList.contains('active')) { answer.style.maxHeight = 'none'; const newHeight = answer.scrollHeight; answer.style.maxHeight = (newHeight + 50) + 'px'; } } }); } }