generated from dellevin/template
111
This commit is contained in:
37
index.html
37
index.html
@@ -42,6 +42,43 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<!-- 搜索功能 -->
|
||||||
|
<div id="search-overlay" class="search-overlay">
|
||||||
|
<div class="search-modal">
|
||||||
|
<button class="search-lock-btn" id="search-lock-btn" title="搜索常驻">
|
||||||
|
<svg id="lock-icon-open" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
|
||||||
|
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
|
||||||
|
</svg>
|
||||||
|
<svg id="lock-icon-closed" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: none;">
|
||||||
|
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
|
||||||
|
<path d="M7 11V7a5 5 0 0 1 9.9-1"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div class="search-box">
|
||||||
|
<div class="search-engine-selector" id="search-engine-selector">
|
||||||
|
<img src="./static/img/search_icon/google.png" alt="Google" id="search-engine-icon" />
|
||||||
|
<div class="search-engine-dropdown" id="search-engine-dropdown">
|
||||||
|
<div class="engine-option active" data-engine="google" data-icon="./static/img/search_icon/google.png">
|
||||||
|
<img src="./static/img/search_icon/google.png" alt="Google" /> Google
|
||||||
|
</div>
|
||||||
|
<div class="engine-option" data-engine="baidu" data-icon="./static/img/search_icon/baidu.png">
|
||||||
|
<img src="./static/img/search_icon/baidu.png" alt="Baidu" /> Baidu
|
||||||
|
</div>
|
||||||
|
<div class="engine-option" data-engine="duckduckgo" data-icon="./static/img/search_icon/DuckDuckGo.png">
|
||||||
|
<img src="./static/img/search_icon/DuckDuckGo.png" alt="DuckDuckGo" /> DuckDuckGo
|
||||||
|
</div>
|
||||||
|
<div class="engine-option" data-engine="yandex" data-icon="./static/img/search_icon/Yandex.png">
|
||||||
|
<img src="./static/img/search_icon/Yandex.png" alt="Yandex" /> Yandex
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="text" id="global-search-input" placeholder="Search..." autocomplete="off" />
|
||||||
|
<button id="global-search-btn">搜索</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="letter-container">
|
<div class="letter-container">
|
||||||
<!-- 语言切换按钮 -->
|
<!-- 语言切换按钮 -->
|
||||||
<div class="lang-switch-container">
|
<div class="lang-switch-container">
|
||||||
|
|||||||
@@ -4,6 +4,177 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 搜索功能样式 */
|
||||||
|
.search-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
z-index: 9999;
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-overlay.active {
|
||||||
|
display: flex;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 常驻搜索模式:背景保持模糊,阻止页面交互 */
|
||||||
|
body.persistent-search-mode .search-overlay {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
pointer-events: auto; /* 确保遮罩层接收点击事件以阻止页面交互 */
|
||||||
|
}
|
||||||
|
|
||||||
|
body.persistent-search-mode .search-modal {
|
||||||
|
pointer-events: auto;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-modal {
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 600px;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-lock-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: -45px;
|
||||||
|
right: 0;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||||
|
color: #fff;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-lock-btn:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.4);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-lock-btn.locked {
|
||||||
|
background: #1a73e8;
|
||||||
|
border-color: #1a73e8;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-overlay.active .search-modal {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||||
|
overflow: visible;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-engine-selector {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-engine-selector:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-engine-selector img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
#global-search-input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 12px 15px;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font-size: 16px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#global-search-btn {
|
||||||
|
padding: 12px 24px;
|
||||||
|
border: none;
|
||||||
|
background: #333;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#global-search-btn:hover {
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-engine-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
margin-top: 8px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
min-width: 180px;
|
||||||
|
display: none;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-engine-dropdown.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engine-option {
|
||||||
|
padding: 12px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engine-option:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engine-option.active {
|
||||||
|
background: #e8f0fe;
|
||||||
|
color: #1a73e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.engine-option img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Georgia', 'Times New Roman', 'STSong', serif;
|
font-family: 'Georgia', 'Times New Roman', 'STSong', serif;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
|
|||||||
BIN
static/img/search_icon/DuckDuckGo.png
Normal file
BIN
static/img/search_icon/DuckDuckGo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
static/img/search_icon/Yandex.png
Normal file
BIN
static/img/search_icon/Yandex.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1000 B |
BIN
static/img/search_icon/baidu.png
Normal file
BIN
static/img/search_icon/baidu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1012 B |
BIN
static/img/search_icon/google.png
Normal file
BIN
static/img/search_icon/google.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,3 +1,195 @@
|
|||||||
|
// ==================== 全局搜索功能 ====================
|
||||||
|
(function() {
|
||||||
|
const searchEngines = {
|
||||||
|
google: 'https://www.google.com/search?q=',
|
||||||
|
baidu: 'https://www.baidu.com/s?wd=',
|
||||||
|
duckduckgo: 'https://duckduckgo.com/?q=',
|
||||||
|
yandex: 'https://yandex.com/search/?text='
|
||||||
|
};
|
||||||
|
|
||||||
|
let currentEngine = localStorage.getItem('search_engine') || 'google';
|
||||||
|
let enterCount = 0;
|
||||||
|
let enterTimer = null;
|
||||||
|
|
||||||
|
const searchOverlay = document.getElementById('search-overlay');
|
||||||
|
const searchLockBtn = document.getElementById('search-lock-btn');
|
||||||
|
const lockIconOpen = document.getElementById('lock-icon-open');
|
||||||
|
const lockIconClosed = document.getElementById('lock-icon-closed');
|
||||||
|
const searchInput = document.getElementById('global-search-input');
|
||||||
|
const searchBtn = document.getElementById('global-search-btn');
|
||||||
|
const searchIcon = document.getElementById('search-engine-icon');
|
||||||
|
const dropdown = document.getElementById('search-engine-dropdown');
|
||||||
|
const engineSelector = document.getElementById('search-engine-selector');
|
||||||
|
const engineOptions = document.querySelectorAll('.engine-option');
|
||||||
|
|
||||||
|
// 检查是否开启常驻模式
|
||||||
|
const isPersistentSearch = localStorage.getItem('persistent_search') === 'true';
|
||||||
|
if (isPersistentSearch) {
|
||||||
|
document.body.classList.add('persistent-search-mode');
|
||||||
|
// 确保搜索框也显示出来
|
||||||
|
if (searchOverlay) {
|
||||||
|
searchOverlay.classList.add('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化搜索引擎图标
|
||||||
|
function updateSearchIcon() {
|
||||||
|
const activeOption = document.querySelector(`.engine-option[data-engine="${currentEngine}"]`);
|
||||||
|
if (activeOption) {
|
||||||
|
const iconSrc = activeOption.getAttribute('data-icon');
|
||||||
|
searchIcon.src = iconSrc;
|
||||||
|
searchIcon.alt = currentEngine.charAt(0).toUpperCase() + currentEngine.slice(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新锁图标状态
|
||||||
|
function updateLockIcon() {
|
||||||
|
const isLocked = document.body.classList.contains('persistent-search-mode');
|
||||||
|
if (isLocked) {
|
||||||
|
lockIconOpen.style.display = 'none';
|
||||||
|
lockIconClosed.style.display = 'block';
|
||||||
|
searchLockBtn.classList.add('locked');
|
||||||
|
searchLockBtn.title = '取消常驻';
|
||||||
|
} else {
|
||||||
|
lockIconOpen.style.display = 'block';
|
||||||
|
lockIconClosed.style.display = 'none';
|
||||||
|
searchLockBtn.classList.remove('locked');
|
||||||
|
searchLockBtn.title = '搜索常驻';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示搜索框
|
||||||
|
function showSearch() {
|
||||||
|
searchOverlay.classList.add('active');
|
||||||
|
setTimeout(() => {
|
||||||
|
searchInput.focus();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐藏搜索框(仅非驻留模式下调用)
|
||||||
|
function hideSearch() {
|
||||||
|
if (document.body.classList.contains('persistent-search-mode')) {
|
||||||
|
return; // 常驻模式下不允许通过此函数关闭
|
||||||
|
}
|
||||||
|
searchOverlay.classList.remove('active');
|
||||||
|
searchInput.value = '';
|
||||||
|
dropdown.classList.remove('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换常驻模式
|
||||||
|
function togglePersistentMode() {
|
||||||
|
const isLocked = document.body.classList.contains('persistent-search-mode');
|
||||||
|
if (isLocked) {
|
||||||
|
// 退出常驻模式(解锁):只改变锁状态,不关闭搜索框
|
||||||
|
document.body.classList.remove('persistent-search-mode');
|
||||||
|
localStorage.setItem('persistent_search', 'false');
|
||||||
|
// 注意:不移除 active 类,保持搜索框显示
|
||||||
|
} else {
|
||||||
|
// 开启常驻模式(锁定)
|
||||||
|
document.body.classList.add('persistent-search-mode');
|
||||||
|
localStorage.setItem('persistent_search', 'true');
|
||||||
|
searchOverlay.classList.add('active');
|
||||||
|
}
|
||||||
|
updateLockIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行搜索
|
||||||
|
function performSearch() {
|
||||||
|
const query = searchInput.value.trim();
|
||||||
|
if (query) {
|
||||||
|
const url = searchEngines[currentEngine] + encodeURIComponent(query);
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听双击回车键
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (enterTimer && (now - enterTimer < 500)) {
|
||||||
|
// 双击回车:如果当前不是常驻模式,则打开/关闭搜索框;如果是常驻模式,则不处理
|
||||||
|
if (!document.body.classList.contains('persistent-search-mode')) {
|
||||||
|
if (searchOverlay.classList.contains('active')) {
|
||||||
|
hideSearch();
|
||||||
|
} else {
|
||||||
|
showSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enterCount = 0;
|
||||||
|
enterTimer = null;
|
||||||
|
} else {
|
||||||
|
enterCount = 1;
|
||||||
|
enterTimer = now;
|
||||||
|
|
||||||
|
// 如果搜索框已经打开,按单下回车执行搜索
|
||||||
|
if (searchOverlay.classList.contains('active') && document.activeElement === searchInput) {
|
||||||
|
performSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ESC 键关闭搜索框(仅在非驻留模式下生效)
|
||||||
|
if (e.key === 'Escape' && searchOverlay.classList.contains('active') && !document.body.classList.contains('persistent-search-mode')) {
|
||||||
|
hideSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 点击搜索引擎图标切换下拉菜单
|
||||||
|
engineSelector.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
dropdown.classList.toggle('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 选择搜索引擎
|
||||||
|
engineOptions.forEach(option => {
|
||||||
|
option.addEventListener('click', () => {
|
||||||
|
currentEngine = option.getAttribute('data-engine');
|
||||||
|
localStorage.setItem('search_engine', currentEngine);
|
||||||
|
|
||||||
|
// 更新激活状态
|
||||||
|
engineOptions.forEach(opt => opt.classList.remove('active'));
|
||||||
|
option.classList.add('active');
|
||||||
|
|
||||||
|
updateSearchIcon();
|
||||||
|
dropdown.classList.remove('show');
|
||||||
|
searchInput.focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 点击页面其他地方关闭下拉菜单
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
// 如果不在常驻模式下,且点击的是搜索框外部,则关闭搜索框
|
||||||
|
if (!document.body.classList.contains('persistent-search-mode') && !searchOverlay.contains(e.target)) {
|
||||||
|
hideSearch();
|
||||||
|
}
|
||||||
|
dropdown.classList.remove('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 阻止下拉菜单内部点击事件冒泡
|
||||||
|
dropdown.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 点击搜索按钮
|
||||||
|
searchBtn.addEventListener('click', performSearch);
|
||||||
|
|
||||||
|
// 点击锁图标切换常驻模式
|
||||||
|
searchLockBtn.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation(); // 阻止事件冒泡,防止触发 document 的点击关闭逻辑
|
||||||
|
togglePersistentMode();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
updateSearchIcon();
|
||||||
|
updateLockIcon();
|
||||||
|
const initialActiveOption = document.querySelector(`.engine-option[data-engine="${currentEngine}"]`);
|
||||||
|
if (initialActiveOption) {
|
||||||
|
engineOptions.forEach(opt => opt.classList.remove('active'));
|
||||||
|
initialActiveOption.classList.add('active');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
// ==================== Umami Stats 请求 ====================
|
// ==================== Umami Stats 请求 ====================
|
||||||
(async () => {
|
(async () => {
|
||||||
const webid = "ae6cd64c-5900-49c9-9c22-95cedc24a508";
|
const webid = "ae6cd64c-5900-49c9-9c22-95cedc24a508";
|
||||||
|
|||||||
Reference in New Issue
Block a user