
在github上搭建部落格時候,唯一使用一點算是後端的環境就是jekyll,但是這個東西設計就是用來生成靜态頁面的。 并沒有設計資料庫什麼的,更不要提搜尋功能了,那怎麼來實作搜尋功能呢?
我的解決思路
全部代碼
Search.prototype = {
constructor: SearchBlog,
// 異步擷取資料内容後的處理函數調用
init: function (xml) {
searchBlogObj.xmlToObjectArray(xml)
searchBlogObj.formTableSubmit()
},
// 異步擷取整個站點文章
getXmlHttpResponse: function () {
var fn = searchBlogObj.init
$.ajax({
url: this.url,
dataType: "xml",
success: function (xml) {
fn(xml)
}
}
)
},
// 将xml轉換為對象的數組
xmlToObjectArray: function (xml) {
var json = []
$(xml).find("*:first").children().each(function (i) {
var obj = {title: $(this).find("title").text(), content: $(this).find("content").text(), url: $(this).find("url").text(),time:$(this).find("time").text()}
json.push(obj)
})
searchBlogObj.json = json
},
// 全站搜尋
fullTextSearch: function (keyword) {
var reg = new RegExp(keyword)
var regArray = []
$.each(searchBlogObj.json, function (n, v) {
if (reg.test(this.title) || reg.test(this.content)) {
regArray.push(this)
}
})
return regArray
},
// 搜尋成功後重新渲染頁面
review: function (regArray) {
$.each(regArray,function(){
})
html
$("#show_post").html(html)
},
// 綁定搜尋輸入框擷取輸入框内容
formTableSubmit: function () {
var thisObj = this
$("#search_form").submit(function (e) {
e.preventDefault();
var regArray = searchBlogObj.fullTextSearch($("#search_input").val())
if (regArray.length === 0) {
alert("沒有搜到任何東西")
return
}
thisObj.review(regArray);
})
}
}
資料來源
思路
我們知道jekyll不但能生成html,也能生成XML(比如生成站點地圖),為什麼不利用這點将網站所有的文章做個XML, 作為檢索用的原始資料,
實作
下面是jekyll實作代碼
<?xml version="1.0" encoding="UTF-8"?>
<blogs>
{ % for post in site.posts % }
<blog>
<title>{ {post.title | xml_escape} }</title>
<content>{ {post.content | xml_escape} }</content>
<url>http://www.yourUrl.com{ {post.url} }</url>
<time>{ { post.date | date: "%Y-%m-%d"} }</time>
</blog>
{ % endfor % }
</blogs>
上面代碼将整個站點的搜尋文章全部列印了出來,這裡要注意一下因為是生成XML,jekyll使用的是Liquid,在生成XML時候如果不使用 XML_escape,逃避一些格式,就會造成jekyll出現錯誤。
資料處理
理論上jquery應該有更好的XML處理辦法,隻是我沒有找到,于是自己寫了JS代碼,将異步讀取的XML轉化為對象的數組
xmlToObjectArray: function (xml) {
var json = []
$(xml).find("*:first").children().each(function (i) {
var obj = {title: $(this).find("title").text(), content: $(this).find("content").text(), url: $(this).find("url").text(),time:$(this).find("time").text()}
json.push(obj)
})
searchBlogObj.json = json
},
内容搜尋
我已經拿到轉換成對象數組的整站資料,現在就是我們搜尋過程,我的搜尋過程比較簡單,一旦
正則比對
出有關鍵字 就将這個對象放在比對成功的數組裡面,實作代碼如下
fullTextSearch: function (keyword) {
var reg = new RegExp(keyword)
var regArray = []
$.each(searchBlogObj.json, function (n, v) {
if (reg.test(this.title) || reg.test(this.content)) {
regArray.push(this)
}
})
return regArray
}
前端實作
上面我們看到的基本就是整個代碼"背景"部分,現在我們要為使用者制作一個輸入關鍵字form表單,這個表單不能真正被送出,而是當點選 送出事件時候,更改點選後的操作處理方法為擷取關鍵字,
formTableSubmit: function () {
var thisObj = this
$("#search_form").submit(function (e) {
e.preventDefault();
var regArray = searchBlogObj.fullTextSearch($("#search_input").val())
if (regArray.length === 0) {
alert("沒有搜到任何東西")
return
}
thisObj.review(regArray);
})
}