天天看點

Github搭建的部落格實作JS搜尋功能

Github搭建的部落格實作JS搜尋功能

在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);
        })
    }