feat(search): 集成多搜索引擎功能

添加Google、Bing、百度外部搜索引擎集成,支持用户通过搜索框右侧图标选择搜索引擎
This commit is contained in:
Zuoling Rong
2025-05-09 15:06:59 +08:00
parent c8174012a2
commit fb32f06f19
3 changed files with 225 additions and 3 deletions

View File

@@ -679,6 +679,68 @@ body .content.expanded {
color: var(--error-color);
}
/* 搜索图标和搜索引擎切换图标位置调整 */
.search-box .search-icon {
right: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
}
.search-box .search-engine-toggle {
right: 3.5rem;
cursor: pointer;
font-size: 0.8rem;
}
/* 搜索引擎下拉菜单 */
.search-engine-dropdown {
position: absolute;
top: calc(100% + 5px);
right: 1rem;
background-color: var(--sidebar-bg);
border-radius: 10px;
box-shadow: 0 4px 15px var(--shadow-color);
display: none;
z-index: 100;
padding: 0.5rem;
border: 1px solid var(--border-color);
}
.search-engine-dropdown.active {
display: flex;
animation: fadeIn 0.2s ease-out forwards;
}
.search-engine-option {
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
margin: 0.3rem;
cursor: pointer;
transition: all 0.2s ease;
background-color: var(--card-bg-gradient-1);
}
.search-engine-option:hover {
background-color: var(--card-bg-gradient-2);
transform: translateY(-2px);
box-shadow: 0 3px 8px var(--shadow-color);
}
.search-engine-option.active {
background-color: var(--accent-color);
color: white;
}
.search-engine-option i {
position: static;
transform: none;
font-size: 1.2rem;
}
/* 页面容器 */
.page {
position: relative;

View File

@@ -8,6 +8,7 @@ document.addEventListener('DOMContentLoaded', () => {
let isLightTheme = false; // 主题状态
let isSidebarCollapsed = false; // 侧边栏折叠状态
let pages; // 页面元素的全局引用
let currentSearchEngine = 'local'; // 当前选择的搜索引擎
// 搜索索引,用于提高搜索效率
let searchIndex = {
@@ -15,12 +16,41 @@ document.addEventListener('DOMContentLoaded', () => {
items: []
};
// 搜索引擎配置
const searchEngines = {
local: {
name: '本地搜索',
icon: 'fas fa-search',
url: null // 本地搜索不需要URL
},
google: {
name: 'Google搜索',
icon: 'fab fa-google',
url: 'https://www.google.com/search?q='
},
bing: {
name: 'Bing搜索',
icon: 'fab fa-microsoft',
url: 'https://www.bing.com/search?q='
},
baidu: {
name: '百度搜索',
icon: 'fas fa-paw',
url: 'https://www.baidu.com/s?wd='
}
};
// 获取DOM元素 - 基本元素
const searchInput = document.getElementById('search');
const searchBox = document.querySelector('.search-box');
const searchResultsPage = document.getElementById('search-results');
const searchSections = searchResultsPage.querySelectorAll('.search-section');
// 搜索引擎相关元素
const searchIcon = document.querySelector('.search-icon');
const searchEngineDropdown = document.querySelector('.search-engine-dropdown');
const searchEngineOptions = document.querySelectorAll('.search-engine-option');
// 移动端元素
const menuToggle = document.querySelector('.menu-toggle');
const searchToggle = document.querySelector('.search-toggle');
@@ -578,16 +608,129 @@ document.addEventListener('DOMContentLoaded', () => {
const debouncedSearch = debounce(performSearch, 300);
searchInput.addEventListener('input', (e) => {
debouncedSearch(e.target.value);
// 只有在选择了本地搜索时,才在输入时实时显示本地搜索结果
if (currentSearchEngine === 'local') {
debouncedSearch(e.target.value);
} else {
// 对于非本地搜索,重置之前的本地搜索结果(如果有)
if (isSearchActive) {
resetSearch();
}
}
});
// 初始化搜索引擎设置
function initSearchEngine() {
// 从本地存储获取上次选择的搜索引擎
const savedEngine = localStorage.getItem('searchEngine');
if (savedEngine && searchEngines[savedEngine]) {
currentSearchEngine = savedEngine;
}
// 设置当前搜索引擎的激活状态及图标
updateSearchEngineUI();
// 初始化搜索引擎下拉菜单事件
searchIcon.addEventListener('click', (e) => {
e.stopPropagation();
searchEngineDropdown.classList.toggle('active');
});
// 点击搜索引擎选项
searchEngineOptions.forEach(option => {
// 初始化激活状态
if (option.getAttribute('data-engine') === currentSearchEngine) {
option.classList.add('active');
}
option.addEventListener('click', (e) => {
e.stopPropagation();
// 获取选中的搜索引擎
const engine = option.getAttribute('data-engine');
// 更新当前搜索引擎
if (engine && searchEngines[engine]) {
// 如果搜索引擎变更,且之前有活跃的本地搜索结果,重置搜索状态
if (currentSearchEngine !== engine && isSearchActive) {
resetSearch();
}
currentSearchEngine = engine;
localStorage.setItem('searchEngine', engine);
// 更新UI显示
updateSearchEngineUI();
// 关闭下拉菜单
searchEngineDropdown.classList.remove('active');
}
});
});
// 点击页面其他位置关闭下拉菜单
document.addEventListener('click', () => {
searchEngineDropdown.classList.remove('active');
});
}
// 更新搜索引擎UI显示
function updateSearchEngineUI() {
// 移除所有选项的激活状态
searchEngineOptions.forEach(option => {
option.classList.remove('active');
// 如果是当前选中的搜索引擎,添加激活状态
if (option.getAttribute('data-engine') === currentSearchEngine) {
option.classList.add('active');
}
});
// 更新搜索图标以反映当前搜索引擎
if (searchIcon) {
// 清除所有类保留基本的search-icon类
const classList = searchIcon.className.split(' ').filter(cls => cls === 'search-icon');
searchIcon.className = classList.join(' ');
// 添加当前搜索引擎的图标类
const engine = searchEngines[currentSearchEngine];
if (engine) {
const iconClasses = engine.icon.split(' ');
iconClasses.forEach(cls => {
searchIcon.classList.add(cls);
});
// 更新标题提示
searchIcon.setAttribute('title', engine.name);
}
}
}
// 执行搜索(根据选择的搜索引擎)
function executeSearch(searchTerm) {
if (!searchTerm.trim()) return;
// 根据当前搜索引擎执行搜索
if (currentSearchEngine === 'local') {
// 执行本地搜索
performSearch(searchTerm);
} else {
// 使用外部搜索引擎
const engine = searchEngines[currentSearchEngine];
if (engine && engine.url) {
// 打开新窗口进行搜索
window.open(engine.url + encodeURIComponent(searchTerm), '_blank');
}
}
}
// 搜索框事件处理
searchInput.addEventListener('keyup', (e) => {
if (e.key === 'Escape') {
searchInput.value = '';
resetSearch();
} else if (e.key === 'Enter') {
performSearch(searchInput.value);
executeSearch(searchInput.value);
// 在移动设备上,执行搜索后自动关闭搜索面板
if (isMobile() && isSearchOpen) {
closeAllPanels();
@@ -618,6 +761,9 @@ document.addEventListener('DOMContentLoaded', () => {
// 初始化侧边栏状态
initSidebarState();
// 初始化搜索引擎选择
initSearchEngine();
// 立即执行初始化不再使用requestAnimationFrame延迟
// 显示首页
showPage('home');

View File

@@ -92,7 +92,21 @@
<div class="search-container">
<div class="search-box">
<input type="text" id="search" placeholder="搜索...">
<i class="fas fa-search"></i>
<i class="fas fa-search search-icon" title="本地搜索"></i>
<div class="search-engine-dropdown">
<div class="search-engine-option" data-engine="local" title="本地搜索">
<i class="fas fa-search"></i>
</div>
<div class="search-engine-option" data-engine="google" title="Google搜索">
<i class="fab fa-google"></i>
</div>
<div class="search-engine-option" data-engine="bing" title="Bing搜索">
<i class="fab fa-microsoft"></i>
</div>
<div class="search-engine-option" data-engine="baidu" title="百度搜索">
<i class="fas fa-paw"></i>
</div>
</div>
</div>
</div>