还记得上一篇文章吗?
https://blog.csdn.net/2503_90553990/article/details/157036170?spm=1001.2014.3001.5501
回想起来,这网站的功能有些单调,想给它加个搜索功能,又不知道该从何下手······
打开我浏览器的chrome://extensions/页面,在一堆扩展里找到了毛若昕老师和杨尚臻老师的"青柠起始页",灵感一下子就来了,正好我的朋友陈青陌老师做了自己的起始页https://star.muah.top/,和青柠很像,还要迎合黑客帝国的风格,不如拿过来抄抄作业!
废话不多说,上代码
```html
<!DOCTYPE html>
<html lang="zh-CN"><head>
<meta charset="UTF-8">
<title>Search Around the World -- 全球联合部署搜索引擎</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext x='10' y='70' font-size='70' fill='%2300ff41'%3E▣%3C/text%3E%3C/svg%3E">
<style>
/* ========= 黑客帝国基调 ========= */
:root{
--matrix:#00ff41;
--bg:#000;
--glass:rgba(0,255,65,.08);
}
*{box-sizing:border-box;}
html,body{height:100%;margin:0;background:var(--bg);color:var(--matrix);font-family:"Courier New",Courier,monospace;overflow:hidden;}
body::before{content:"";position:fixed;inset:0;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="f"><feTurbulence baseFrequency=".9"/><feColorMatrix values="0 0 0 0 .11 0 0 0 0 .13 0 0 0 0 .17 0 0 0 1 0"/></filter><rect width="100%" height="100%" filter="url(%23f)" opacity=".3"/></svg>');pointer-events:none;z-index:1;}
canvas#rain{position:fixed;inset:0;width:100%;height:100%;z-index:2;pointer-events:none;}
/* ========= 布局 ========= */
#info,#corner{position:fixed;font-size:12px;text-shadow:0 0 3px var(--matrix);z-index:10;}
#info{top:8px;left:8px;}
#corner{bottom:8px;right:8px;text-align:right;}
.wrapper{height:100%;display:flex;align-items:center;justify-content:center;transform:translateY(-15%);z-index:5;position:relative;}
.box{width:90%;max-width:520px;text-align:center;}
/* ========= 标题 ========= */
.box h1{font-size:3.2rem;margin:0 0 1.2rem;font-weight:300;letter-spacing:1px;cursor:pointer;white-space:nowrap;text-shadow:0 0 6px var(--matrix);}
/* ========= 搜索框 ========= */
.box form{display:flex;height:48px;border:1px solid var(--matrix);box-shadow:0 0 10px var(--matrix);background:var(--glass);border-radius:4px;overflow:hidden;backdrop-filter:blur(4px);}
.box select{flex:0 0 76px;border:none;background:transparent;color:var(--matrix);padding:0 8px;font-size:.9rem;outline:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="12" height="8"%3E%3Cpath fill="%2300ff41" d="M6 8L0 0h12z"/%3E%3C/svg%3E');background-repeat:no-repeat;background-position:right 8px center;background-size:.6rem;}
.box input{flex:1 1 0;border:none;background:transparent;color:var(--matrix);padding:0 .8rem;font-size:1rem;outline:none;}
.box input::placeholder{color:var(--matrix);opacity:.6;}
.box button{flex:0 0 48px;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;}
.box button svg{width:22px;height:22px;fill:var(--matrix);}
/* ========= 历史记录 ========= */
#histList{width:100%;margin:8px 0;background:var(--glass);border:1px solid var(--matrix);border-radius:4px;max-height:0;overflow:hidden;transition:max-height .25s;z-index:10;backdrop-filter:blur(4px);}
#histList.show{max-height:280px;}
#histList .item{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;font-size:.95rem;cursor:pointer;border-bottom:1px solid rgba(0,255,65,.2);}
#histList .item:hover{background:rgba(0,255,65,.15);}
#histList .item .txt{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left;}
#histList .item .del{flex:0 0 auto;margin-left:8px;color:#999;font-size:12px;padding:2px 6px;border-radius:3px;background:rgba(255,0,0,.2);}
#histList .item .del:hover{background:rgba(255,0,0,.4);}
/* ========= 图标栏 ========= */
#iconBar{margin-top:14px;display:flex;justify-content:space-between;gap:8px;position:relative;}
#iconBar .ibtn{flex:1;height:40px;border:1px solid var(--matrix);background:var(--glass);color:var(--matrix);border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .2s,box-shadow .2s;}
#iconBar .ibtn:hover{background:rgba(0,255,65,.25);box-shadow:0 0 8px var(--matrix);}
#iconBar .ibtn svg{height:20px;fill:var(--matrix);}
/* ========= 下拉菜单 ========= */
.pop-menu{position:absolute;top:100%;left:0;right:0;margin:6px 0 0 0;background:var(--glass);border:1px solid var(--matrix);border-radius:4px;max-height:0;overflow:hidden;transition:max-height .25s;z-index:20;backdrop-filter:blur(4px);}
.pop-menu.show{max-height:320px;}
.pop-menu a{display:block;padding:10px 12px;font-size:.95rem;color:var(--matrix);text-decoration:none;border-bottom:1px solid rgba(0,255,65,.2);}
.pop-menu a:hover{background:rgba(0,255,65,.15);}
.pop-menu::before{content:"";position:absolute;top:-6px;left:50%;transform:translateX(-50%);width:0;height:0;border-style:solid;border-width:0 6px 6px 6px;border-color:transparent transparent var(--matrix) transparent;}
</style>
</head>
<body>
<canvas id="rain"></canvas>
<div id="info">
<div id="runTime">站点运行时间:计算中...</div>
<div id="curTime">当前时间:加载中...</div>
<div id="ip">IP 地址:获取中...</div>
</div>
<div id="corner">
<div>频道:1007658011</div>
<div>作者:𝓢𝓴𝔂𝓽𝓻𝓪𝓵 𝓥𝓪𝓷𝓽𝓻𝓪𝓷𝓼𝓮𝓷</div>
<div>链接:https://tunhs.mysxl.cn/\</div>
</div>
<div class="wrapper">
<div class="box">
<h1 id="clock" title="时间">--:--</h1>
<form id="searchForm" onsubmit="doSearch();return false">
<select id="engineSelect" aria-label="搜索引擎">
<option value="bing" data-url="https://www.bing.com/search?q= ">必应</option>
<option value="google" data-url="https://www.google.com/search?q= ">谷歌</option>
<option value="360" data-url="https://www.so.com/s?q= ">360</option>
<option value="sogou" data-url="https://www.sogou.com/web?query= ">搜狗</option>
<option value="baidu" data-url="https://www.baidu.com/s?word= ">百度</option>
</select>
<input type="text" name="q" placeholder="输入指令..." required>
<button type="submit">
<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 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>
</form>
<div id="histList"></div>
<div id="iconBar">
<button class="ibtn" data-menu="video" title="视频"><svg viewBox="0 0 24 24"><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7l7 4z"/></svg></button>
<button class="ibtn" data-menu="picture" title="图片"><svg viewBox="0 0 24 24"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM5 19V5h14v14H5zm3-5l2.5 3.01L14 12l4 6H7z"/></svg></button>
<button class="ibtn" data-menu="music" title="音乐"><svg viewBox="0 0 24 24"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg></button>
<button class="ibtn" data-menu="game" title="游戏"><svg viewBox="0 0 24 24"><path d="M21 6H3c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-10 7H8v3H6v-3H3v-2h3V8h2v3h3v2zm4.5 2c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4-3c-.83 0-1.5-.67-1.5-1.5S18.67 9 19.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/></svg></button>
<button class="ibtn" data-menu="friendship" title="友谊"><svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"/></svg></button>
</div>
<div class="pop-menu" id="popMenu"></div>
</div>
</div>
<script>
/* ========= 字符雨 ========= */
const canvas=document.getElementById('rain'),ctx=canvas.getContext('2d');
let cols,drops;font=14;
function resize(){canvas.width=innerWidth;canvas.height=innerHeight;cols=Math.floor(canvas.width/font);drops=Array(cols).fill(0).map(()=>Math.random()*-100);}
onresize=resize;resize();
function rain(){
ctx.fillStyle='rgba(0,0,0,.05)';ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle='#00ff41';ctx.font=font+'px Courier';
for(let i=0;i<cols;i++){
const text=String.fromCharCode(0x30A0+Math.random()*96);
ctx.fillText(text,i*font,drops[i]*font);
if(drops[i]*font>canvas.height&&Math.random()>.975)drops[i]=0;
drops[i]++;
}
}
setInterval(rain,35);
/* ========= 原功能移植 ========= */
const startTime=new Date('2025/12/29 14:00:00').getTime();
const runEl=document.getElementById('runTime'),timeEl=document.getElementById('curTime'),ipEl=document.getElementById('ip');
function fmtDuration(ms){
const d=Math.floor(ms/86400000),h=Math.floor(ms%86400000/3600000),m=Math.floor(ms%3600000/60000),s=Math.floor(ms%60000/1000);
return `{d}天 {h}时 {m}分 {s}秒`;
}
function updateRun(){runEl.textContent='站点运行时间:'+fmtDuration(Date.now()-startTime);}
updateRun();setInterval(updateRun,1000);
function updateCur(){timeEl.textContent='当前时间:'+new Date().toLocaleString('zh-CN',{hour12:false});}
updateCur();setInterval(updateCur,1000);
const clock=document.getElementById('clock'),week=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
let baseText='--:--';
function updateBase(){
const now=new Date();
baseText=String(now.getHours()).padStart(2,'0')+':'+String(now.getMinutes()).padStart(2,'0');
if(!clock.matches(':hover'))clock.textContent=baseText;
}
updateBase();setInterval(updateBase,500);
if(matchMedia('(hover:hover)').matches){
clock.addEventListener('mouseenter',()=>{
const n=new Date();
clock.textContent=`{n.getFullYear()}/{String(n.getMonth()+1).padStart(2,'0')}/{String(n.getDate()).padStart(2,'0')} {week[n.getDay()]}`;
});
clock.addEventListener('mouseleave',()=>clock.textContent=baseText);
}
const MAX_HIST=5,histKey='searchHist',input=document.querySelector('input[name="q"]'),histList=document.getElementById('histList');
let histData=JSON.parse(localStorage.getItem(histKey)||'[]');
const engineName={bing:'必应',google:'谷歌','360':'360',sogou:'搜狗',baidu:'百度'};
function escapeHtml(str){
return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');
}
function saveHist(){localStorage.setItem(histKey,JSON.stringify(histData));}
function renderHist(){
const kw=input.value.trim().toLowerCase();
const filtered=kw?histData.filter(h=>h.query.toLowerCase().includes(kw)):histData;
if(!filtered.length){histList.classList.remove('show');return;}
histList.innerHTML=filtered.map((h,i)=>`
<div class="item" data-index="${i}">
<span class="txt">{escapeHtml(engineName\[h.engine\])}:{escapeHtml(h.query)}</span>
<span class="del">删除</span>
</div>`).join('');
histList.classList.add('show');
}
function addHist(query,engine){
histData=histData.filter(h=>!(h.query===query&&h.engine===engine));
histData.unshift({query,engine});
if(histData.length>MAX_HIST)histData=histData.slice(0,MAX_HIST);
saveHist();
}
input.addEventListener('focus',renderHist);
input.addEventListener('input',renderHist);
histList.addEventListener('click',e=>{
const item=e.target.closest('.item');if(!item)return;
if(e.target.classList.contains('del')){
const i=Number(item.dataset.index);
histData.splice(i,1);saveHist();renderHist();
if(!histData.length)histList.classList.remove('show');
return;
}
const h=histData[Number(item.dataset.index)];
input.value=h.query;document.getElementById('engineSelect').value=h.engine;
histList.classList.remove('show');input.focus();
});
document.addEventListener('click',e=>{if(!e.target.closest('.box'))histList.classList.remove('show');});
const select=document.getElementById('engineSelect');
const saved=localStorage.getItem('lastEngine');
if(saved)select.value=saved;
function doSearch(){
const opt=select.selectedOptions[0];
const query=input.value.trim();if(!query)return;
addHist(query,select.value);
const url=opt.dataset.url+encodeURIComponent(query);
localStorage.setItem('lastEngine',select.value);
window.open(url,'_blank');
}
const menuData={
video:[
{name:'哔哩哔哩',url:'https://www.bilibili.com'},
{name:'油管',url:'https://www.youtube.com'},
{name:'抖音',url:'https://www.douyin.com'},
{name:'快手',url:'https://www.kuaishou.com'},
{name:'爱奇艺',url:'https://www.iqiyi.com'},
{name:'腾讯视频',url:'https://v.qq.com'},
{name:'好看视频',url:'https://haokan.baidu.com'}
],
picture:[
{name:'百度识图',url:'https://shitu.baidu.com'},
{name:'谷歌图库',url:'https://fonts.google.com/icons'}
],
music:[
{name:'网易云音乐',url:'https://music.163.com'},
{name:'QQ音乐',url:'https://y.qq.com'},
{name:'酷狗音乐',url:'https://www.kugou.com'}
],
game:[
{name:'4399小游戏平台',url:'https://www.4399.com'},
{name:'IMC群组网络',url:'https://games.imc.re'},
{name:'POKI宝玩',url:'https://poki.com'}
],
friendship:[
{name:'NekoFile',url:'https://nekofile.com/'},
{name:'GitHub',url:'https://github.com/'},
{name:'一只猫娘',url:'https://cat.muah.top/'},
{name:'热铁盒软件',url:'https://retiehe.com/'},
{name:'青陌合集',url:'https://tool.muah.top/'},
{name:'菜鸟工具',url:'https://www.jyshare.com/'}
]
};
const popMenu=document.getElementById('popMenu');let activeMenu=null;
function closeMenu(){popMenu.classList.remove('show');activeMenu=null;}
function openMenu(key){
if(activeMenu===key){closeMenu();return;}
activeMenu=key;
popMenu.innerHTML=menuData[key].map(m=>`<a href="{m.url}" target="_blank"\>{m.name}</a>`).join('');
popMenu.classList.add('show');
}
document.querySelectorAll('#iconBar .ibtn').forEach(btn=>btn.addEventListener('click',()=>openMenu(btn.dataset.menu)));
document.addEventListener('click',e=>{if(!e.target.closest('#iconBar')&&!e.target.closest('#popMenu'))closeMenu();});
</script>
</body></html>
好了,有时间我会把它拼到上一篇文章那个个人主页里的,就此搁笔。