一个多引擎一键搜索 可多分组

经验创意 · 176 次浏览
-阿修- 创建于 2026-05-22 01:36

按tab键可切换搜索分组,按管理打开编辑模式

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>浮岛分组搜索 Pro</title>

<style>
html,body{
  margin:0;
  width:100%;
  height:100%;
  overflow:hidden;
  background:transparent;
  font-family:"Microsoft YaHei",sans-serif;
}

.card{
  width:100%;
  height:100%;
  box-sizing:border-box;
  padding:12px;
  border-radius:18px;
  background:linear-gradient(135deg,#0b1220,#0f172a 55%,#0a0f1c);
  border:1px solid rgba(120,180,255,.18);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 10px 30px rgba(0,0,0,.35);
  display:flex;
  flex-direction:column;
  gap:10px;
}

.top{
  display:flex;
  gap:8px;
}

input{
  flex:1;
  height:38px;
  border-radius:12px;
  border:1px solid rgba(255,255,255,.08);
  background:rgba(255,255,255,.04);
  color:#e5e7eb;
  padding:0 12px;
  outline:none;
}

button{
  height:38px;
  padding:0 12px;
  border-radius:12px;
  border:1px solid rgba(59,130,246,.35);
  background:rgba(59,130,246,.22);
  color:#fff;
  cursor:pointer;
}

/* 横向分组栏 */
.groupBar{
  display:flex;
  gap:6px;
  overflow-x:auto;
  padding-bottom:4px;
  scrollbar-width:none;
}

.groupBar::-webkit-scrollbar{
  display:none;
}

.groupTab{
  flex-shrink:0;
  padding:6px 10px;
  border-radius:999px;
  font-size:12px;
  color:rgba(200,220,255,.8);
  border:1px solid rgba(255,255,255,.08);
  background:rgba(255,255,255,.03);
  cursor:pointer;
  transition:.15s;
  white-space:nowrap;
}

.groupTab.active{
  background:rgba(59,130,246,.25);
  border-color:rgba(120,180,255,.35);
  color:#fff;
}

.addTab{
  color:#9ecbff;
}

.panel{
  flex:1;
  overflow-y:auto;
  border-radius:12px;
  background:rgba(255,255,255,.02);
  border:1px solid rgba(255,255,255,.05);
  padding:8px;
}

.item{
  display:flex;
  justify-content:space-between;
  padding:8px;
  border-radius:10px;
  margin-bottom:6px;
  background:rgba(255,255,255,.02);
  border:1px solid rgba(255,255,255,.04);
  cursor:pointer;
}

.item:hover{
  background:rgba(255,255,255,.05);
}

.name{color:#e5e7eb;font-size:13px;}
.url{font-size:11px;color:rgba(147,197,253,.7);max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
</style>
</head>

<body>

<div class="card">

  <div class="top">
    <input id="input" placeholder="输入搜索内容">
    <button id="search">搜索</button>
    <button id="manage">管理</button>
  </div>

  <div class="groupBar" id="groupBar"></div>

  <div class="panel" id="panel"></div>

</div>

<script>
(function(){

let manage=false;

let data={
  current:0,
  groups:[
    {name:"影视",sites:[
      {name:"B站影视",url:"https://search.bilibili.com/all?keyword={q} 剧"}
    ]},
    {name:"图片",sites:[
      {name:"Pinterest",url:"https://www.pinterest.com/search/pins/?q={q}"}
    ]},
    {name:"全部",sites:[
      {name:"Google",url:"https://www.google.com/search?q={q}"},
      {name:"B站",url:"https://search.bilibili.com/all?keyword={q}"}
    ]}
  ]
};

const input=document.getElementById("input");
const bar=document.getElementById("groupBar");
const panel=document.getElementById("panel");

function ready(){ return window.fudao && window.fudao.invoke; }

async function load(){
  if(ready()){
    try{
      const r=await window.fudao.invoke("state.read",{key:"groups",defaultValue:JSON.stringify(data)});
      data=JSON.parse(r||JSON.stringify(data));
    }catch(e){}
  }
  render();
}

async function save(){
  if(ready()){
    await window.fudao.invoke("state.write",{key:"groups",value:JSON.stringify(data)});
  }
}

function renderGroups(){
  bar.innerHTML="";

  // 按顺序渲染:普通分组 + 全部放最后
  const normalGroups=data.groups.filter(g=>g.name!=="全部");
  const allGroups=data.groups.filter(g=>g.name==="全部");
  const renderList=[...normalGroups,...allGroups];

  renderList.forEach((g,i)=>{
    const idx=data.groups.indexOf(g);
    const tab=document.createElement("div");
    tab.className="groupTab"+(idx===data.current?" active":"");
    tab.innerText=g.name;
    tab.onclick=()=>{
      data.current=idx;
      render();
      save();
    };
    bar.appendChild(tab);
  });

  if(manage){
    const add=document.createElement("div");
    add.className="groupTab addTab";
    add.innerText="+ 新增";
    add.onclick=()=>{
      const name=prompt("分组名");
      if(name){
        data.groups.push({name,sites:[]});
        render();save();
      }
    };
    bar.appendChild(add);
  }
}

function renderSites(){
  const g=data.groups[data.current];
  panel.innerHTML="";

  g.sites.forEach((s,i)=>{
    const div=document.createElement("div");
    div.className="item";
    div.innerHTML=`
      <div>
        <div class="name">${s.name}</div>
        <div class="url">${s.url}</div>
      </div>
      <div>
        ${manage?'<button>✏</button><button>🗑</button>':''}
      </div>
    `;
    div.onclick=()=>{ if(!manage) open(s.url); };
    panel.appendChild(div);
  });

  if(manage){
    const add=document.createElement("div");
    add.className="item";
    add.innerHTML="<div class='name'>+ 新增网站</div>";
    add.onclick=()=>{
      const name=prompt("网站名");
      const url=prompt("URL (用 {q})");
      if(name && url){ g.sites.push({name,url}); render(); save(); }
    };
    panel.appendChild(add);
  }
}

function open(url){
  const q=encodeURIComponent(input.value.trim());
  if(!q) return;
  const final=url.replace("{q}",q);
  if(ready()){
    window.fudao.invoke("url.open",{url:final});
  }else{
    window.open(final);
  }
}

function render(){
  renderGroups();
  renderSites();
}

document.getElementById("manage").onclick=()=>{ manage=!manage; render(); };
document.getElementById("search").onclick=()=>{ data.groups[data.current].sites.forEach(s=>open(s.url)); };
input.addEventListener("keydown",e=>{
  if(e.key==="Tab"){ e.preventDefault(); data.current=(data.current+1)%data.groups.length; render(); save(); }
  if(e.key==="Enter"){ document.getElementById("search").click(); }
});

setTimeout(load,300);

})();
</script>

</body>
</html>

-阿修- 最后更新于 2026/5/22

回复内容
暂无回复
回复主贴