You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

540 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 搜索功能JavaScript文件
* 实现搜索框的弹出/收起动画和交互功能
* 包含新闻搜索模块的交互功能
*/
// 新闻搜索模块功能
(function() {
'use strict';
// 等待DOM加载完成
document.addEventListener('DOMContentLoaded', function() {
initNewsSearch();
});
function initNewsSearch() {
const searchInput = document.getElementById('news-search');
const categorySelect = document.getElementById('news-category');
const searchForm = document.querySelector('.news-search-form');
const suggestionsContainer = document.getElementById('search-suggestions');
if (!searchInput || !categorySelect || !searchForm) {
return;
}
// 搜索建议数据(可以从后端获取)
let searchSuggestions = [];
let currentSuggestionIndex = -1;
// 分类下拉动画
categorySelect.addEventListener('focus', function() {
this.style.transform = 'scale(1.02)';
});
categorySelect.addEventListener('blur', function() {
this.style.transform = 'scale(1)';
});
// 分类选择改变时自动提交表单
categorySelect.addEventListener('change', function() {
const selectedOption = this.options[this.selectedIndex];
const url = selectedOption.getAttribute('data-url');
const searchVal = searchInput.value.trim();
// 如果搜索词为空且有目标URL直接跳转用于“显示全部”或切换分类
if (searchVal === '' && url) {
window.location.href = url;
} else {
searchForm.submit();
}
});
// 搜索输入框事件
searchInput.addEventListener('input', function() {
const query = this.value.trim();
if (query.length >= 2) {
fetchSearchSuggestions(query);
} else {
hideSuggestions();
}
});
// 键盘事件处理
searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
if (currentSuggestionIndex >= 0 && searchSuggestions[currentSuggestionIndex]) {
this.value = searchSuggestions[currentSuggestionIndex];
hideSuggestions();
}
searchForm.submit();
} else if (e.key === 'ArrowDown') {
e.preventDefault();
navigateSuggestions(1);
} else if (e.key === 'ArrowUp') {
e.preventDefault();
navigateSuggestions(-1);
} else if (e.key === 'Escape') {
hideSuggestions();
}
});
// 点击外部隐藏建议
document.addEventListener('click', function(e) {
if (!searchInput.contains(e.target) && !suggestionsContainer.contains(e.target)) {
hideSuggestions();
}
});
// 获取搜索建议
function fetchSearchSuggestions(query) {
// 模拟搜索建议实际项目中应该从后端API获取
const mockSuggestions = [
'新能源汽车',
'新能源政策',
'新能源技术',
'新能源发展',
'新能源投资',
'太阳能发电',
'风能发电',
'储能技术',
'电池技术',
'充电桩建设'
];
searchSuggestions = mockSuggestions.filter(item =>
item.toLowerCase().includes(query.toLowerCase())
).slice(0, 5);
showSuggestions();
}
// 显示搜索建议
function showSuggestions() {
if (searchSuggestions.length === 0) {
hideSuggestions();
return;
}
let html = '';
searchSuggestions.forEach((suggestion, index) => {
html += `<div class="suggestion-item" data-index="${index}">${suggestion}</div>`;
});
suggestionsContainer.innerHTML = html;
suggestionsContainer.classList.add('show');
// 绑定建议项点击事件
suggestionsContainer.querySelectorAll('.suggestion-item').forEach(item => {
item.addEventListener('click', function() {
searchInput.value = this.textContent;
hideSuggestions();
searchForm.submit();
});
item.addEventListener('mouseenter', function() {
currentSuggestionIndex = parseInt(this.dataset.index);
updateSuggestionHighlight();
});
});
}
// 隐藏搜索建议
function hideSuggestions() {
suggestionsContainer.classList.remove('show');
currentSuggestionIndex = -1;
}
// 导航搜索建议
function navigateSuggestions(direction) {
if (searchSuggestions.length === 0) return;
currentSuggestionIndex += direction;
if (currentSuggestionIndex < 0) {
currentSuggestionIndex = searchSuggestions.length - 1;
} else if (currentSuggestionIndex >= searchSuggestions.length) {
currentSuggestionIndex = 0;
}
updateSuggestionHighlight();
}
// 更新建议高亮
function updateSuggestionHighlight() {
const items = suggestionsContainer.querySelectorAll('.suggestion-item');
items.forEach((item, index) => {
if (index === currentSuggestionIndex) {
item.classList.add('active');
} else {
item.classList.remove('active');
}
});
}
// 表单提交处理
searchForm.addEventListener('submit', function(e) {
const query = searchInput.value.trim();
const category = categorySelect.value;
if (!query && !category) {
e.preventDefault();
searchInput.focus();
return;
}
// 添加加载动画
const searchButton = searchForm.querySelector('.search-button');
if (searchButton) {
searchButton.style.opacity = '0.7';
searchButton.style.transform = 'scale(0.95)';
}
});
// 平滑的焦点动画
searchInput.addEventListener('focus', function() {
this.parentElement.style.transform = 'scale(1.02)';
this.parentElement.style.boxShadow = '0 0 0 3px rgba(0, 123, 255, 0.1)';
});
searchInput.addEventListener('blur', function() {
this.parentElement.style.transform = 'scale(1)';
this.parentElement.style.boxShadow = 'none';
});
}
// 页面加载完成后初始化新闻搜索功能
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initNewsSearch);
} else {
initNewsSearch();
}
})();
(function() {
'use strict';
// DOM元素
let searchToggle, searchOverlay, searchInput, searchClose, searchForm;
// 初始化函数
function initSearch() {
// 获取DOM元素
searchToggle = document.getElementById('searchToggle');
searchOverlay = document.getElementById('searchOverlay');
searchInput = document.getElementById('searchInput');
searchClose = document.getElementById('searchClose');
searchForm = document.querySelector('.search-form');
if (!searchToggle || !searchOverlay) {
return;
}
// 绑定事件
bindEvents();
// 初始化GSAP动画如果可用
if (typeof gsap !== 'undefined') {
initGSAPAnimations();
}
}
// 绑定事件
function bindEvents() {
// 搜索按钮点击事件
searchToggle.addEventListener('click', openSearch);
// 关闭按钮点击事件
if (searchClose) {
searchClose.addEventListener('click', closeSearch);
}
// 遮罩层点击事件
searchOverlay.addEventListener('click', function(e) {
if (e.target === searchOverlay) {
closeSearch();
}
});
// ESC键关闭搜索
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && searchOverlay.classList.contains('active')) {
closeSearch();
}
});
// 搜索表单提交事件
if (searchForm) {
searchForm.addEventListener('submit', handleSearchSubmit);
}
// 搜索输入框事件
if (searchInput) {
searchInput.addEventListener('input', handleSearchInput);
searchInput.addEventListener('focus', handleSearchFocus);
searchInput.addEventListener('blur', handleSearchBlur);
}
}
// 打开搜索框
function openSearch() {
searchOverlay.classList.add('active');
searchToggle.classList.add('active');
document.body.style.overflow = 'hidden';
// 延迟聚焦到输入框
setTimeout(() => {
if (searchInput) {
searchInput.focus();
}
}, 400);
// 触发自定义事件
document.dispatchEvent(new CustomEvent('searchOpened'));
}
// 关闭搜索框
function closeSearch() {
searchOverlay.classList.remove('active');
searchToggle.classList.remove('active');
document.body.style.overflow = '';
// 清空输入框(可选)
if (searchInput) {
// searchInput.value = '';
}
// 触发自定义事件
document.dispatchEvent(new CustomEvent('searchClosed'));
}
// 处理搜索表单提交
function handleSearchSubmit(e) {
const query = searchInput.value.trim();
if (!query) {
e.preventDefault();
searchInput.focus();
// 添加震动效果
if (typeof gsap !== 'undefined') {
gsap.to(searchInput, {
x: [-10, 10, -8, 8, -6, 6, -4, 4, -2, 2, 0],
duration: 0.6,
ease: "power2.out"
});
} else {
searchInput.classList.add('shake');
setTimeout(() => {
searchInput.classList.remove('shake');
}, 600);
}
return false;
}
// 可以在这里添加搜索分析代码
if (typeof gtag !== 'undefined') {
gtag('event', 'search', {
search_term: query
});
}
}
// 处理搜索输入
function handleSearchInput(e) {
const query = e.target.value.trim();
// 可以在这里实现实时搜索建议
if (query.length >= 2) {
// debounce搜索请求
clearTimeout(handleSearchInput.timeout);
handleSearchInput.timeout = setTimeout(() => {
fetchSearchSuggestions(query);
}, 300);
} else {
hideSuggestions();
}
}
// 搜索输入框获得焦点
function handleSearchFocus() {
searchInput.parentElement.classList.add('focused');
}
// 搜索输入框失去焦点
function handleSearchBlur() {
searchInput.parentElement.classList.remove('focused');
}
// 获取搜索建议(示例实现)
function fetchSearchSuggestions(query) {
// 这里可以实现AJAX搜索建议
// 示例向WordPress REST API发送请求
/*
fetch(`${themeData.ajaxUrl}?action=search_suggestions&query=${encodeURIComponent(query)}&nonce=${themeData.nonce}`)
.then(response => response.json())
.then(data => {
if (data.success) {
showSuggestions(data.data);
}
})
.catch(error => {
console.error('搜索建议获取失败:', error);
});
*/
}
// 显示搜索建议
function showSuggestions(suggestions) {
let suggestionsContainer = document.querySelector('.search-suggestions');
if (!suggestionsContainer) {
suggestionsContainer = document.createElement('div');
suggestionsContainer.className = 'search-suggestions';
searchInput.parentElement.appendChild(suggestionsContainer);
}
if (suggestions && suggestions.length > 0) {
suggestionsContainer.innerHTML = suggestions.map(item =>
`<div class="search-suggestion-item" data-value="${item.title}">${item.title}</div>`
).join('');
// 绑定建议项点击事件
suggestionsContainer.querySelectorAll('.search-suggestion-item').forEach(item => {
item.addEventListener('click', function() {
searchInput.value = this.dataset.value;
hideSuggestions();
searchForm.submit();
});
});
suggestionsContainer.classList.add('show');
} else {
hideSuggestions();
}
}
// 隐藏搜索建议
function hideSuggestions() {
const suggestionsContainer = document.querySelector('.search-suggestions');
if (suggestionsContainer) {
suggestionsContainer.classList.remove('show');
}
}
// 初始化GSAP动画
function initGSAPAnimations() {
// 注册ScrollTrigger插件如果可用
if (typeof ScrollTrigger !== 'undefined') {
gsap.registerPlugin(ScrollTrigger);
}
// 搜索按钮悬停动画
searchToggle.addEventListener('mouseenter', function() {
gsap.to(this.querySelector('.search-icon'), {
rotation: 90,
scale: 1.1,
duration: 0.3,
ease: "back.out(1.7)"
});
});
searchToggle.addEventListener('mouseleave', function() {
gsap.to(this.querySelector('.search-icon'), {
rotation: 0,
scale: 1,
duration: 0.3,
ease: "back.out(1.7)"
});
});
// 自定义搜索框打开动画
document.addEventListener('searchOpened', function() {
const searchBox = document.querySelector('.search-box');
const searchInputWrapper = document.querySelector('.search-input-wrapper');
const searchSubmit = document.querySelector('.search-submit');
// 重置初始状态
gsap.set([searchBox, searchInputWrapper, searchSubmit], {
opacity: 0,
y: 30,
scale: 0.9
});
// 创建时间线动画
const tl = gsap.timeline();
tl.to(searchBox, {
opacity: 1,
y: 0,
scale: 1,
duration: 0.4,
ease: "back.out(1.7)"
})
.to(searchInputWrapper, {
opacity: 1,
y: 0,
scale: 1,
duration: 0.3,
ease: "power2.out"
}, "-=0.2")
.to(searchSubmit, {
opacity: 1,
y: 0,
scale: 1,
duration: 0.3,
ease: "power2.out"
}, "-=0.1");
});
}
// 工具函数:防抖
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 工具函数:节流
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSearch);
} else {
initSearch();
}
// 导出到全局(用于调试)
window.ThemeSearch = {
open: openSearch,
close: closeSearch,
toggle: function() {
if (searchOverlay && searchOverlay.classList.contains('active')) {
closeSearch();
} else {
openSearch();
}
}
};
})();