使用JS給靜態(tài)頁(yè)面添加搜索功能的實(shí)現(xiàn)方法
背景
靜態(tài)頁(yè)面通常由HTML、CSS 和 JavaScript 等靜態(tài)文件組成,這些文件在服務(wù)器上不會(huì)動(dòng)態(tài)生成或修改,所以加載速度通常比較快。也利于搜索引擎的抓取,適合用于展示固定內(nèi)容的網(wǎng)站,如企業(yè)官方網(wǎng)站、產(chǎn)品介紹頁(yè)、博客文章等。
為網(wǎng)頁(yè)添加搜索模塊的第三方網(wǎng)站有不少,首先我嘗試了一下谷歌的站內(nèi)搜索,讓人比較痛苦的一個(gè)是前幾行都是谷歌廣告,而且還去不掉,還有一點(diǎn)就是搜索結(jié)果只能展示谷歌收錄的頁(yè)面,比如我網(wǎng)站加上小語(yǔ)種至少有幾千個(gè)頁(yè)面了,但是谷歌實(shí)際收錄的頁(yè)面只有幾百,也就是說(shuō)百分之80-90的結(jié)果都展示不出來(lái),這兩點(diǎn)就讓人很絕望了,不得不另謀他路。

解決方案
從網(wǎng)上摸索了一圈,終于找到了一種比較簡(jiǎn)單的使用 js 實(shí)現(xiàn)的搜索功能,經(jīng)過(guò)幾番倒騰終于可以成功復(fù)現(xiàn)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search Example</title>
<style>
#searchInput {
margin-bottom: 10px;
}
.urlset li {
display: none;
}
.pagination {
margin-top: 10px;
}
</style>
</head>
<body>
<input type="text" id="searchInput" placeholder="輸入關(guān)鍵字">
<ul class="urlset">
<li class="aurl"><a rel="external nofollow" data-lastfrom="" title="Peptide Expert & Quality Proteins & Ubiquitins factory">Peptide Expert & Quality Proteins & Ubiquitins factory</a></li>
<li class="aurl"><a rel="external nofollow" data-lastfrom="" title="chat with us">chat with us</a></li>
<li class="aurl"><a rel="external nofollow" data-lastfrom="" title="China Hefei KS-V Peptide Biological Technology Co.Ltd company profile">China Hefei KS-V Peptide Biological Technology Co.Ltd company profile</a></li>
<!-- 此處省略一萬(wàn)條鏈接 -->
</ul>
<script>
document.getElementById('searchInput').addEventListener('input', function () {
var searchKeyword = this.value.toLowerCase();
var links = document.querySelectorAll('.urlset a');
links.forEach(function (link) {
var title = link.getAttribute('title').toLowerCase();
var url = link.getAttribute('href').toLowerCase();
if (title.includes(searchKeyword) || url.includes(searchKeyword)) {
link.parentNode.style.display = 'block';
} else {
link.parentNode.style.display = 'none';
}
});
});
</script>
</body>
</html>
效果如下:

到這里我們已經(jīng)初步完成了一個(gè)簡(jiǎn)陋的搜索功能,頁(yè)面不多的個(gè)人博客、小型企業(yè)站其實(shí)已經(jīng)可以拿來(lái)用了。但是當(dāng)我們頁(yè)面比較多,比如有300+頁(yè)面,那么上面光一個(gè)搜索功能就需要接近400行的代碼,每個(gè)頁(yè)面都放入這400行代碼,直接300*400,加重服務(wù)器的負(fù)擔(dān),影響頁(yè)面加載速度,維護(hù)起來(lái)也十分困難。
優(yōu)化方法
首先我們將這些鏈接+標(biāo)題都放入一個(gè)xml中,格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<links>
<link>
<url>https://www.ks-vpeptide.com/</url>
<title>Peptide Expert & Quality Proteins & Ubiquitins factory</title>
</link>
<link>
<url>https://www.ks-vpeptide.com/webim/webim_tab.html</url>
<title>chat with us</title>
</link>
<link>
<url>https://www.ks-vpeptide.com/aboutus.html</url>
<title>China Hefei KS-V Peptide Biological Technology Co.Ltd company profile</title>
</link>
<!-- 此處省略一萬(wàn)條<link></link> -->
<link>
<url>https://www.ks-vpeptide.com/buy-h4k12ac.html</url>
<title>Buy h4k12ac, Good quality h4k12ac manufacturer</title>
</link>
<link>
<url>https://www.ks-vpeptide.com/contactnow.html</url>
<title>Send your inquiry directly to us</title>
</link>
</links>
頁(yè)面較多的可以用工具生成xml,我這保存了一個(gè)可以免費(fèi)生成網(wǎng)站站點(diǎn)地圖的工具:sitemap.zhetao.com/

該工具有一點(diǎn)較好的是它生成的格式有多種供選擇,缺點(diǎn)就是一個(gè)站點(diǎn)180天只能生成一次,挺難受的。

到這里我們把之前的代碼修改一下,
<body>
<!-- hysousuo -->
<input type="text" id="searchInput" placeholder="輸入關(guān)鍵字">
<ul class="urlset">
<!-- 鏈接將在這里動(dòng)態(tài)加載 -->
</ul>
<script>
document.getElementById('searchInput').addEventListener('input', function () {
var searchKeyword = this.value.toLowerCase();
<!-- your_links.xml 換成你的 xml 名稱(chēng) -->
fetch('your_links.xml')
.then(response => response.text())
.then(data => {
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(data, 'application/xml');
var links = xmlDoc.querySelectorAll('link');
links.forEach(function (link) {
var url = link.querySelector('url').textContent.toLowerCase();
var title = link.querySelector('title').textContent.toLowerCase();
var li = document.createElement('li');
li.className = 'aurl';
li.innerHTML = `<a href="${url}" rel="external nofollow" rel="external nofollow" data-lastfrom="" title="${title}">${title}</a>`;
document.querySelector('.urlset').appendChild(li);
if (title.includes(searchKeyword) || url.includes(searchKeyword)) {
li.style.display = 'block';
} else {
li.style.display = 'none';
}
});
})
.catch(error => console.error('Error fetching XML:', error));
});
</script>
</body>
改完之后我發(fā)現(xiàn)搜索結(jié)果出不來(lái)了,看了下控制臺(tái)的報(bào)錯(cuò),原來(lái)是瀏覽器的同源策略導(dǎo)致的,該策略要求網(wǎng)頁(yè)中使用的所有腳本(包括 JavaScript、CSS、圖片等)都必須來(lái)自同一源(協(xié)議、域名和端口)。

在這種情況下,我的頁(yè)面是通過(guò) file:/// 協(xié)議打開(kāi)的,而 XML 文件路徑是絕對(duì)路徑 C:/Users/18363/Documents/HBuilderProjects/demo/your links.xml。這導(dǎo)致了跨源請(qǐng)求,因?yàn)?file:/// 協(xié)議和 C: 協(xié)議不同。
解決方法:將文件上傳至服務(wù)器中運(yùn)行。試了一下果然好了

在加入我們網(wǎng)站時(shí)我們需要將搜索結(jié)果置于頁(yè)面頂層(指的是里外的最外層),所以還需要再加一段CSS,最終完整代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search Example</title>
<style>
#searchInput {
margin-bottom: 10px;
}
.searchResults {
position: absolute;
top: 60px; /* 調(diào)整彈窗的垂直位置 */
left: 10px;
z-index: 999; /* 確保彈窗在最上層 */
background-color: white;
border: 1px solid #ccc;
padding: 10px;
display: none;
}
.searchResults li {
list-style-type: none;
}
</style>
</head>
<body>
<!-- hysousuo -->
<!-- 搜索框 -->
<form>
<input type="text" id="searchInput" placeholder="Search Keywords or Catalog Number">
</form>
<!-- 搜索結(jié)果 -->
<ul class="searchResults">
<!-- 搜索結(jié)果將會(huì)動(dòng)態(tài)加載到這里 -->
</ul>
<!-- JavaScript 代碼 -->
<script>
const searchInput = document.getElementById('searchInput');
const searchResultsContainer = document.querySelector('.searchResults');
searchInput.addEventListener('input', function () {
const searchKeyword = this.value.toLowerCase();
// 清空之前的搜索結(jié)果
searchResultsContainer.innerHTML = '';
if (searchKeyword.trim() === '') {
// 如果搜索關(guān)鍵字為空,隱藏彈窗并返回
searchResultsContainer.style.display = 'none';
return;
}
fetch('https://ks-vpeptide.haiyong.site/your_links.xml')
.then(response => response.text())
.then(data => {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data, 'application/xml');
const links = xmlDoc.querySelectorAll('link');
let hasResults = false;
links.forEach(link => {
const url = link.querySelector('url').textContent.toLowerCase();
const title = link.querySelector('title').textContent.toLowerCase();
if (title.includes(searchKeyword) || url.includes(searchKeyword)) {
const li = document.createElement('li');
li.className = 'aurl';
li.innerHTML = `<a href="${url}" rel="external nofollow" rel="external nofollow" data-lastfrom="" title="${title}">${title}</a>`;
searchResultsContainer.appendChild(li);
hasResults = true;
}
});
// 根據(jù)搜索結(jié)果顯示或隱藏彈窗
searchResultsContainer.style.display = hasResults ? 'block' : 'none';
})
.catch(error => console.error('Error fetching XML:', error));
});
// 監(jiān)聽(tīng)輸入框失去焦點(diǎn)事件,隱藏搜索結(jié)果彈窗
searchInput.addEventListener('blur', function () {
// 使用 setTimeout 確保點(diǎn)擊搜索結(jié)果時(shí)能觸發(fā)鏈接
setTimeout(() => {
searchResultsContainer.style.display = 'none';
}, 200);
});
</script>
最終實(shí)現(xiàn)效果:

樣式還有點(diǎn)奇怪,還需要再調(diào)整一下,其他沒(méi)什么問(wèn)題了,如果大家有需要幫助,可以在下方評(píng)論區(qū)告訴我,有什么其他添加搜索功能的好辦法也可以分享出來(lái)給大家參考。
總結(jié)
本文介紹了靜態(tài)頁(yè)面添加搜索功能的問(wèn)題、解決方案和優(yōu)化方法,通過(guò)實(shí)例演示了如何利用 JavaScript 動(dòng)態(tài)加載 XML 中的數(shù)據(jù)實(shí)現(xiàn)搜索功能,為需要在靜態(tài)頁(yè)面中添加搜索功能的讀者提供了一定價(jià)值的參考。
以上就是使用JS給靜態(tài)頁(yè)面添加搜索功能的實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于JS靜態(tài)頁(yè)面添加搜索功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
前端js中的事件循環(huán)eventloop機(jī)制詳解
這篇文章主要給大家介紹了關(guān)于前端js中事件循環(huán)eventloop機(jī)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
javascript使用正則表達(dá)式實(shí)現(xiàn)去掉空格之后的字符
這篇文章主要介紹了javascript使用正則表達(dá)式實(shí)現(xiàn)去掉空格之后的字符的方法,需要的朋友可以參考下2015-02-02
結(jié)合ES6?編寫(xiě)?JavaScript?設(shè)計(jì)模式中的結(jié)構(gòu)型模式
這篇文章主要介紹了結(jié)合ES6編寫(xiě)JavaScript?設(shè)計(jì)模式中的結(jié)構(gòu)型模式,設(shè)計(jì)模式是軟件設(shè)計(jì)中常見(jiàn)問(wèn)題的解決方案,這些模式很容易重復(fù)使用并且富有表現(xiàn)力2022-07-07
JavaScript實(shí)現(xiàn)彈出子窗口并傳值給父窗口
這篇文章主要介紹了JavaScript實(shí)現(xiàn)彈出子窗口并傳值給父窗口,方法很簡(jiǎn)單,這里推薦給大家,需要的朋友可以參考下2014-12-12
js 定義對(duì)象數(shù)組(結(jié)合)多維數(shù)組方法
下面小編就為大家?guī)?lái)一篇js 定義對(duì)象數(shù)組(結(jié)合)多維數(shù)組方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
微信小程序語(yǔ)音同步智能識(shí)別的實(shí)現(xiàn)案例代碼解析
在一些小程序的開(kāi)發(fā)場(chǎng)景中經(jīng)常會(huì)有語(yǔ)音轉(zhuǎn)文字的需求,今天小編通過(guò)實(shí)際案例給大家分享微信小程序語(yǔ)音同步智能識(shí)別功能,需要的朋友可以參考下2020-05-05
用JS簡(jiǎn)單實(shí)現(xiàn)九宮格抽獎(jiǎng)的示例代碼
在網(wǎng)上經(jīng)??匆?jiàn)一些抽獎(jiǎng)頁(yè)面,也玩過(guò)不同類(lèi)型的抽獎(jiǎng)活動(dòng),但是一直沒(méi)有做過(guò)抽獎(jiǎng)的功能,所以今天來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的九宮格抽獎(jiǎng)功能,文中有詳細(xì)的代碼示例供大家參考,感興趣的朋友可以自己動(dòng)手嘗試一下2023-12-12

