// ==UserScript==
// @name 全局动画资源搜索工具
// @namespace http://tampermonkey.net/
// @version 0.0.2
// @description 这个脚本提供了美观的用户界面和便捷的搜索功能,让您可以快速在多个动画资源网站中搜索内容,在任何网页上使用快捷键[Shift+F]即可呼出动画资源搜索引擎
// @author Aomine
// @match *://*/*
// @icon data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'><text x='0' y='24' font-size='24'>🔍 </text></svg>
// @license GPL License
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 创建搜索框HTML结构
const searchHTML = `
<div id="search-overlay"></div>
<div id="global-search-container">
<div class="search-header">
<h2 class="search-title">动画资源搜索</h2>
<button class="close-btn">×</button>
</div>
<div class="search-input-group">
<input type="text" id="search-input" placeholder="输入动画名称..." autocomplete="off">
<button id="search-btn">
<svg class="search-icon" viewBox="0 0 24 24">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
</svg>
</button>
</div>
<div class="engine-selector">
<label class="engine-label">选择搜索引擎:</label>
<select id="engine-select">
<option value="0">次元城</option>
<option value="1">稀饭动漫</option>
<option value="2">MuteFun</option>
<option value="3">咕咕番</option>
<option value="4">NT动漫</option>
<option value="5">风铃动漫</option>
<option value="6">喵物次元</option>
</select>
</div>
<div class="search-footer">
按 <span class="search-hotkey">ESC</span> 关闭 | 按 <span class="search-hotkey">Enter</span> 搜索
</div>
</div>
`;
// 创建CSS样式
const css = `
#global-search-container {
position: fixed;
top: 20%;
left: 50%;
transform: translateX(-50%);
z-index: 999999;
background: rgba(255, 255, 255, 0.95);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.18);
padding: 20px;
width: 550px;
max-width: 90%;
display: none;
animation: pop-in 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
#search-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(3px);
z-index: 999998;
display: none;
}
@keyframes pop-in {
0% { opacity: 0; transform: translate(-50%, -20px); }
100% { opacity: 1; transform: translate(-50%, 0); }
}
.search-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.search-title {
font-size: 20px;
font-weight: 600;
color: #2c3e50;
margin: 0;
}
.close-btn {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #7f8c8d;
transition: color 0.2s;
}
.close-btn:hover {
color: #e74c3c;
}
.search-input-group {
display: flex;
margin-bottom: 15px;
border-radius: 30px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
}
#search-input {
flex: 1;
padding: 15px 20px;
border: none;
outline: none;
font-size: 16px;
background: #f8f9fa;
}
#search-btn {
background: #3498db;
border: none;
padding: 0 25px;
cursor: pointer;
transition: background 0.3s;
display: flex;
align-items: center;
justify-content: center;
}
#search-btn:hover {
background: #2980b9;
}
.search-icon {
width: 22px;
height: 22px;
fill: white;
}
.engine-selector {
display: flex;
flex-direction: column;
margin-top: 15px;
}
.engine-label {
font-size: 14px;
margin-bottom: 8px;
color: #34495e;
font-weight: 500;
}
#engine-select {
padding: 12px 15px;
border-radius: 8px;
border: 1px solid #ddd;
background: #f8f9fa;
font-size: 15px;
outline: none;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
cursor: pointer;
}
#engine-select:focus {
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}
.search-footer {
margin-top: 15px;
font-size: 13px;
color: #7f8c8d;
text-align: center;
padding-top: 10px;
border-top: 1px solid #eee;
}
.search-hotkey {
background: #f1f2f6;
padding: 2px 6px;
border-radius: 4px;
font-weight: 600;
}
`;
// 将样式和HTML添加到文档
document.head.insertAdjacentHTML('beforeend', `<style>${css}</style>`);
document.body.insertAdjacentHTML('beforeend', searchHTML);
// 搜索引擎列表
const searchEngines = [
{
name: "次元城",
url: "https://www.cycani.org/search.html?wd=${name}"
},
{
name: "稀饭动漫",
url: "https://dm.xifanacg.com/search.html?wd=${name}"
},
{
name: "MuteFun",
url: "https://www.mutean.com/vodsearch/${name}-------------.html"
},
{
name: "咕咕番",
url: "https://www.gugu3.com/index.php/vod/search.html?wd=${name}"
},
{
name: "NT动漫",
url: "http://www.ntdm8.com/search/-------------.html?wd=${name}&page=1"
},
{
name: "风铃动漫",
url: "https://www.aafun.cc/feng-s.html?wd=${name}&submit="
},
{
name: "喵物次元",
url: "https://www.mwcy.net/search.html?wd=${name}"
}
];
// 获取DOM元素
const searchContainer = document.getElementById('global-search-container');
const searchOverlay = document.getElementById('search-overlay');
const searchInput = document.getElementById('search-input');
const searchBtn = document.getElementById('search-btn');
const engineSelect = document.getElementById('engine-select');
const closeBtn = document.querySelector('.close-btn');
// 显示搜索框
function showSearch() {
searchContainer.style.display = 'block';
searchOverlay.style.display = 'block';
searchInput.focus();
document.body.style.overflow = 'hidden';
}
// 隐藏搜索框
function hideSearch() {
searchContainer.style.display = 'none';
searchOverlay.style.display = 'none';
searchInput.value = '';
document.body.style.overflow = '';
}
// 执行搜索
function performSearch() {
const searchTerm = searchInput.value.trim();
if (!searchTerm) return;
const selectedEngine = searchEngines[engineSelect.value];
const encodedTerm = encodeURIComponent(searchTerm);
const searchUrl = selectedEngine.url.replace('${name}', encodedTerm);
window.open(searchUrl, '_blank');
hideSearch();
}
// 事件监听
document.addEventListener('keydown', function(e) {
// Shift + F 打开搜索框
if (e.shiftKey && e.key === 'F') {
e.preventDefault();
showSearch();
}
// ESC 关闭搜索框
if (e.key === 'Escape' && searchContainer.style.display === 'block') {
hideSearch();
}
// 在搜索框中按Enter搜索
if (e.key === 'Enter' && document.activeElement === searchInput && searchContainer.style.display === 'block') {
performSearch();
}
});
searchBtn.addEventListener('click', performSearch);
closeBtn.addEventListener('click', hideSearch);
searchOverlay.addEventListener('click', hideSearch);
})();