feat(search): 集成多搜索引擎功能
添加Google、Bing、百度外部搜索引擎集成,支持用户通过搜索框右侧图标选择搜索引擎
This commit is contained in:
@@ -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;
|
||||
|
||||
148
src/script.js
148
src/script.js
@@ -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) => {
|
||||
// 只有在选择了本地搜索时,才在输入时实时显示本地搜索结果
|
||||
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');
|
||||
|
||||
@@ -92,8 +92,22 @@
|
||||
<div class="search-container">
|
||||
<div class="search-box">
|
||||
<input type="text" id="search" placeholder="搜索...">
|
||||
<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>
|
||||
|
||||
<!-- 页面容器 -->
|
||||
|
||||
Reference in New Issue
Block a user