帝国cms浮动搜索插件现代化、响应式的浮动搜索解决方案,提升网站用户体验
核心特性
🎯智能位置切换
支持左右位置自定义,点击悬停箭头即可切换位置。右侧显示向左箭头,左侧显示向右箭头,操作直观便捷。
🔍优雅搜索体验
搜索框平滑展开动画,左侧位置自动调整内边距确保文字完整显示。支持回车键快速提交搜索。
📱完全响应式设计
自动适配各种屏幕尺寸,在移动设备上智能调整按钮大小和间距,确保最佳用户体验。
⚡智能导航按钮
根据页面滚动位置智能显示导航按钮,使用平滑的透明度变化避免闪烁,提升交互体验。
🎨高度可定制
提供完整的配置选项,支持颜色、尺寸、位置等全方位自定义,轻松匹配网站设计风格。
💾用户偏好记忆
自动保存用户的位置设置,下次访问时保持用户选择,提供一致的使用体验。
使用指南
1.基础交互
插件默认显示在页面右下角。点击搜索按钮展开搜索框,输入关键词后点击搜索或按回车键提交。
// 点击搜索按钮展开搜索框
// 输入关键词后提交搜索
2.位置切换
将鼠标悬停在搜索按钮上显示方向箭头。点击箭头即可在左右位置间切换,无需刷新页面。
// 悬停显示方向箭头
// 点击箭头切换位置
3.智能导航
页面可滚动时显示上下导航按钮。平滑滚动到页面顶部或底部,按钮状态智能变化无闪烁。
// 滚动时显示导航按钮
// 点击平滑滚动到对应位置
4.响应式适配
在不同设备上自动调整布局。移动端优化按钮尺寸和搜索框宽度,确保操作便捷。
// 自动适配移动端
// 优化触控体验
插件代码
把下面代码加入尾部代码就可以,不用修改模版任何代码。
<!-- 插件代码开始 - 只需将这部分代码复制到任何网页的尾部 -->
<div id="floating-search-plugin"></div>
<script>
// ==================== 配置区域 ====================
const CONFIG = {
position: 'right', // 'left' 或 'right'
searchAction: '[!--news.url--]e/search/index.php',
distances: {
right: '30px',
left: '30px',
bottom: '-38px'
}
};
// 创建插件样式
const pluginStyle = document.createElement('style');
pluginStyle.textContent = `
#floating-search-plugin {
position: fixed;
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
z-index: 10000;
}
#floating-search-plugin.position-right {
right: ${CONFIG.distances.right};
bottom: ${CONFIG.distances.bottom};
}
#floating-search-plugin.position-left {
left: ${CONFIG.distances.left};
bottom: ${CONFIG.distances.bottom};
}
.fs-plugin-search-toggle {
background: white;
color: #3498db;
border: 3px solid #3498db;
width: 70px;
height: 70px;
border-radius: 50%;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.4);
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: 600;
position: relative;
z-index: 101;
}
.fs-plugin-search-toggle:hover {
background: #3498db;
color: white;
transform: translateY(-3px) scale(1.05);
box-shadow: 0 6px 20px rgba(52, 152, 219, 0.6);
}
.search-hover-indicator {
position: absolute;
width: 30px;
height: 30px;
opacity: 0;
transition: all 0.4s ease;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 102;
}
#floating-search-plugin.position-right .search-hover-indicator {
left: -35px;
top: 50%;
transform: translateY(-50%);
}
#floating-search-plugin.position-right .fs-plugin-search-toggle:hover .search-hover-indicator {
opacity: 1;
left: -40px;
}
#floating-search-plugin.position-right .search-hover-indicator::before {
content: '‹';
font-size: 32px;
color: #3498db;
font-weight: bold;
}
#floating-search-plugin.position-left .search-hover-indicator {
right: -35px;
top: 50%;
transform: translateY(-50%);
}
#floating-search-plugin.position-left .fs-plugin-search-toggle:hover .search-hover-indicator {
opacity: 1;
right: -40px;
}
#floating-search-plugin.position-left .search-hover-indicator::before {
content: '›';
font-size: 32px;
color: #3498db;
font-weight: bold;
}
.fs-plugin-nav-btn {
background: white;
color: #2c3e50;
border: 3px solid #2c3e50;
width: 60px;
height: 60px;
border-radius: 50%;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
justify-content: center;
}
.fs-plugin-nav-btn.hidden {
display: none;
}
.fs-plugin-nav-btn:hover:not(.hidden) {
background: #2c3e50;
color: white;
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}
.fs-plugin-progress-btn {
background: transparent;
color: #27ae60;
border: none;
width: auto;
height: auto;
min-width: 50px;
min-height: 50px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: bold;
padding: 10px;
opacity: 0;
visibility: hidden;
}
.fs-plugin-progress-btn.visible {
opacity: 1;
visibility: visible;
}
.fs-plugin-progress-btn:hover {
background: rgba(39, 174, 96, 0.1);
transform: translateY(-3px);
border-radius: 8px;
}
.arrow-up::before, .arrow-down::before {
content: '▲';
font-size: 24px;
font-weight: bold;
display: block;
transform: translateY(-1px);
}
.arrow-down::before {
transform: rotate(180deg) translateY(-1px);
}
.fs-plugin-search-wrapper {
position: relative;
display: flex;
align-items: center;
}
.fs-plugin-search-container {
position: absolute;
width: 0;
overflow: hidden;
transition: all 0.4s ease;
z-index: 100;
opacity: 0;
border-radius: 35px;
background: white;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.2);
}
#floating-search-plugin.position-right .fs-plugin-search-container {
right: 0;
transform: translateX(20px);
}
#floating-search-plugin.position-right .fs-plugin-search-container.active {
width: 350px;
opacity: 1;
transform: translateX(0);
}
#floating-search-plugin.position-left .fs-plugin-search-container {
left: 0;
transform: translateX(-20px);
}
#floating-search-plugin.position-left .fs-plugin-search-container.active {
width: 350px;
opacity: 1;
transform: translateX(0);
}
.fs-plugin-search-form {
display: flex;
width: 100%;
height: 70px;
align-items: center;
border-radius: 35px;
overflow: hidden;
}
.fs-plugin-search-input {
flex: 1;
border: none;
background: transparent;
font-size: 16px;
outline: none;
height: 100%;
}
#floating-search-plugin.position-right .fs-plugin-search-input {
padding: 15px 25px 15px 20px;
}
#floating-search-plugin.position-left .fs-plugin-search-input {
padding: 15px 20px 15px 80px;
}
.fs-plugin-search-input::placeholder {
color: #a0a0a0;
}
@media (max-width: 768px) {
#floating-search-plugin.position-right {
right: 20px;
bottom: 20px;
}
#floating-search-plugin.position-left {
left: 20px;
bottom: 20px;
}
.fs-plugin-search-toggle {
width: 65px;
height: 65px;
font-size: 15px;
}
.fs-plugin-nav-btn {
width: 55px;
height: 55px;
}
.fs-plugin-progress-btn {
min-width: 45px;
min-height: 45px;
font-size: 14px;
padding: 8px;
}
.fs-plugin-search-container.active {
width: 280px;
}
.fs-plugin-search-form {
height: 65px;
}
#floating-search-plugin.position-right .fs-plugin-search-input {
padding: 15px 20px 15px 15px;
}
#floating-search-plugin.position-left .fs-plugin-search-input {
padding: 15px 15px 15px 60px;
}
}
`;
document.head.appendChild(pluginStyle);
// 创建插件
document.addEventListener('DOMContentLoaded', function() {
const pluginContainer = document.getElementById('floating-search-plugin');
// 加载用户设置
function loadUserSettings() {
const savedPosition = localStorage.getItem('fs-plugin-position');
if (savedPosition) CONFIG.position = savedPosition;
}
// 保存用户设置
function saveUserSettings() {
localStorage.setItem('fs-plugin-position', CONFIG.position);
}
// 计算滚动进度
function calculateScrollProgress() {
const windowHeight = window.innerHeight;
const documentHeight = document.body.scrollHeight;
const scrollTop = window.pageYOffset;
if (documentHeight <= windowHeight) return 0;
const progress = (scrollTop / (documentHeight - windowHeight)) * 100;
return Math.min(Math.max(progress, 0), 100);
}
// 检查是否需要显示导航按钮
function checkNavButtonsVisibility() {
const windowHeight = window.innerHeight;
const documentHeight = document.body.scrollHeight;
// 如果页面高度不超过窗口高度,隐藏导航按钮
const shouldHideNavButtons = documentHeight <= windowHeight;
if (shouldHideNavButtons) {
toTopBtn.classList.add('hidden');
toBottomBtn.classList.add('hidden');
} else {
toTopBtn.classList.remove('hidden');
toBottomBtn.classList.remove('hidden');
checkNavButtonsState();
}
}
// 检查导航按钮状态(禁用/启用)
function checkNavButtonsState() {
const scrollTop = window.pageYOffset;
const windowHeight = window.innerHeight;
const documentHeight = document.body.scrollHeight;
toTopBtn.classList.toggle('hidden', scrollTop < 50);
toBottomBtn.classList.toggle('hidden', scrollTop + windowHeight >= documentHeight - 50);
}
// 更新进度显示
function updateProgressDisplay() {
const progress = calculateScrollProgress();
const roundedProgress = Math.round(progress);
if (roundedProgress > 0) {
progressBtn.textContent = `${roundedProgress}%`;
progressBtn.classList.add('visible');
// 颜色变化
if (progress > 80) {
progressBtn.style.color = '#27ae60';
} else if (progress > 50) {
progressBtn.style.color = '#f39c12';
} else {
progressBtn.style.color = '#e74c3c';
}
} else {
progressBtn.classList.remove('visible');
}
}
// 初始化
loadUserSettings();
pluginContainer.className = `position-${CONFIG.position}`;
// 创建搜索组件
const searchWrapper = document.createElement('div');
searchWrapper.className = 'fs-plugin-search-wrapper';
const searchToggle = document.createElement('button');
searchToggle.className = 'fs-plugin-search-toggle';
searchToggle.textContent = '搜索';
searchToggle.type = 'button';
const hoverIndicator = document.createElement('div');
hoverIndicator.className = 'search-hover-indicator';
hoverIndicator.title = '点击切换位置';
searchToggle.appendChild(hoverIndicator);
const searchContainer = document.createElement('div');
searchContainer.className = 'fs-plugin-search-container';
const searchForm = document.createElement('form');
searchForm.className = 'fs-plugin-search-form';
searchForm.action = CONFIG.searchAction;
searchForm.method = 'post';
const hiddenInputs = document.createElement('div');
hiddenInputs.style.display = 'none';
hiddenInputs.innerHTML = `
<input type="hidden" name="show" value="title" />
<input type="hidden" name="tempid" value="1" />
<input type="hidden" name="tbname" value="news" />
`;
const searchInput = document.createElement('input');
searchInput.className = 'fs-plugin-search-input';
searchInput.name = 'keyboard';
searchInput.type = 'text';
searchInput.placeholder = '请输入关键词...';
searchForm.appendChild(hiddenInputs);
searchForm.appendChild(searchInput);
searchContainer.appendChild(searchForm);
searchWrapper.appendChild(searchContainer);
searchWrapper.appendChild(searchToggle);
// 创建导航按钮
const toTopBtn = document.createElement('button');
toTopBtn.className = 'fs-plugin-nav-btn arrow-up';
const toBottomBtn = document.createElement('button');
toBottomBtn.className = 'fs-plugin-nav-btn arrow-down';
// 创建进度按钮
const progressBtn = document.createElement('button');
progressBtn.className = 'fs-plugin-progress-btn';
progressBtn.title = '阅读进度';
// 添加到容器
pluginContainer.appendChild(searchWrapper);
pluginContainer.appendChild(toTopBtn);
pluginContainer.appendChild(toBottomBtn);
pluginContainer.appendChild(progressBtn);
// 交互功能
let isSearchExpanded = false;
// 切换位置
function togglePluginPosition() {
CONFIG.position = CONFIG.position === 'right' ? 'left' : 'right';
pluginContainer.className = `position-${CONFIG.position}`;
saveUserSettings();
searchContainer.classList.remove('active');
isSearchExpanded = false;
}
// 事件监听
searchToggle.addEventListener('click', function(event) {
if (event.target === hoverIndicator) return;
if (!isSearchExpanded) {
searchContainer.classList.add('active');
isSearchExpanded = true;
setTimeout(() => searchInput.focus(), 400);
} else {
searchForm.submit();
}
});
hoverIndicator.addEventListener('click', function(event) {
event.stopPropagation();
togglePluginPosition();
});
searchInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') searchForm.submit();
});
document.addEventListener('click', function(event) {
if (!searchToggle.contains(event.target) && !searchContainer.contains(event.target)) {
searchContainer.classList.remove('active');
isSearchExpanded = false;
}
});
toTopBtn.addEventListener('click', function() {
if (!this.classList.contains('hidden')) {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
});
toBottomBtn.addEventListener('click', function() {
if (!this.classList.contains('hidden')) {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
}
});
progressBtn.addEventListener('click', function() {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
// 滚动监听
let scrollTimeout;
window.addEventListener('scroll', function() {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(() => {
checkNavButtonsState();
updateProgressDisplay();
}, 100);
});
// 窗口大小变化监听
window.addEventListener('resize', function() {
checkNavButtonsVisibility();
checkNavButtonsState();
updateProgressDisplay();
});
// 初始化
checkNavButtonsVisibility();
updateProgressDisplay();
});
</script>
<!-- 插件代码结束 -->