typeahead.js 使用教程小結

前言:
最近有個輸入框自動補全的需求,例如百度搜索功能:前端

clipboard.png

在輸入框輸入信息後,自動提示補全。我選擇用typeahead.js,後來發現,原來這個庫的相關學習資料不多,搞的稍微有點久,才弄明白點...
本文實屬原創,若有錯誤,敬請指教!jquery

簡介:git

官網:http://twitter.github.io/typeahead.js
github: https://github.com/twitter/typeahead.js
使用文檔:https://www.awesomes.cn/repo/twitter/typeahead-jsgithub

在查資料的過程當中,不難發現,typeahead.js一直會跟boostrap扯上關係。實際上在bootstrap 2.x時,自帶了補全控件typeahead;可是到了,bootstrap 3.x時,捨棄了這個插件,這是出現了單獨插件,名叫bootstrap-3-typeahead,再後面bootstrap-3-typeahead 更名 typeahead.js.ajax

實踐:正則表達式

由於typeahead的更新變更老是很大,因此每一個版本的改動也很大,而typeahead因此依賴的庫也出現了稍微的變化。下面介紹兩種方法:
第一個bower安裝,也是比較能保證依賴文件的準確性:json

在項目裏面$ bower install typeahead.jsbootstrap

第二種手動引用:
先下載最新版的typeahead.js,以及全部相關依賴。點我點我下載~
下載後,會是下面這幾個文件:數組

clipboard.png
詳解:緩存

  • bloodhound.js(獨立建議引擎)

  • typeahead.jquery.js(獨立的typeahead庫)

  • typeahead.bundle.js(bloodhound+typeahead.jquery的組合體)

注:bloodhound.js和typeahead.jquery.js對jQuery 1.9+依賴。


Examples:
一、基礎示例
Html代碼:

<div class="example">
        <h2>基本示例</h2>
        <div id="basic-example">
            <input class="typeahead" type="text" placeholder="請輸入省份">
        </div>
    </div>

js代碼:

jQuery(function () {
            /*** 1.基本示例 ***/
            var provinces = ["廣東省", "海南省", "山西省", "山東省","湖北省", "湖南省", "陝西省", "上海市", "北京市", "廣西省"];

            var substringMatcher = function (strs) {
                return function findMatches(q, cb) {
                    var matches, substrRegex;
                    matches = [];//定義字符串數組
                    substrRegex = new RegExp(q, 'i');
                    //用正則表達式來肯定哪些字符串包含子串的'q'
                    $.each(strs, function (i, str) {
                    //遍歷字符串池中的任何字符串
                        if (substrRegex.test(str)) {
                            matches.push({ value: str });
                        }
                    //包含子串的'q',將它添加到'match'
                    });
                    cb(matches);
                };
            };

            $('#basic-example .typeahead').typeahead({
                highlight: true,
                minLength: 1
            },
            {
                name: 'provinces',
                displayKey: 'value',
                source: substringMatcher(provinces)
            });

        });

效果圖下(請忽略醜醜的UI):

clipboard.png
數據爲:

var provinces = ["廣東省", "海南省", "山西省", "山東省","湖北省", "湖南省", "陝西省", "上海市", "北京市", "廣西省"];

---------- 華麗麗的分割線 ----------

下面爲要介紹兩種用ajax獲取遠程數據的模式:
第一種是prefetch,是對數據請求一次,把全部數據拿下來。
第二種是remote,只有當觸發輸入框的時候,數據才從服務端獲取。

二、ajax數據預讀示例(prefetch)

Html代碼爲:

<div class="example">
        <h2>Ajax數據預讀示例</h2>
        <div id="ajax-prefetch-example">
            <input class="typeahead" type="text" placeholder="請輸入省份">
        </div>
    </div>

JS代碼爲:

/*** 2.Ajax數據預讀示例 ***/

    // 遠程數據源
    var prefetch_provinces = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        // 預獲取並緩存
        prefetch: '././data/provinces.json'
    });

    prefetch_provinces.initialize();

    $('#ajax-prefetch-example .typeahead').typeahead({
        hint: true,
        highlight: true,
        minLength: 1
    }
    , {
        name: 'provinces',
        displayKey: 'value',
        source: prefetch_provinces.ttAdapter()
    });

數據爲:

[
    {
        "Id":1,
        "value": "廣東省"
    },
    {
        "Id":2,
        "value": "海南省"
    },
    {
        "Id":3,
        "value": "山西省"
    },
    {
        "Id":4,
        "value": "山東省"
    },
    {
        "Id":5,
        "value": "湖北省"
    },
    {
        "Id":6,
        "value": "湖南省"
    },
    {
        "Id":7,
        "value": "陝西省"
    },
    {
        "Id":8,
        "value": "上海市"
    },
    {
        "Id":9,
        "value": "北京市"
    },
    {
        "Id":10,
        "value": "廣西省"
    }
]

文件結構爲:

clipboard.png

效果以下:

clipboard.png

這時候咱們發現了一個問題,當你輸入一個「海」字,是否還能跟示例1同樣,出現「海南省」和「上海市」呢?答案看圖:

clipboard.png

結果是不能!!
爲何呢??哈哈~由於相比示例1,示例2沒有嚴謹的正則表達式再作篩選,改進方法是本身再添加多一個正則判斷!

3.Ajax及時獲取數據示例(remote)

Html代碼:

<div class="example">
        <h2>Ajax及時獲取數據示例</h2>
        <div id="ajax-remote-example">
            <input class="typeahead" type="text" placeholder="請輸入城市">
        </div>
    </div>

JS代碼爲:

/*** 3.Ajax及時獲取數據示例 ***/
        //遠程數據源
        var remote_cities = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('CityName'),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            // 在文本框輸入字符時才發起請求
            remote: '././ajax/GetCities?q=%QUERY'
        });
        remote_cities.initialize();
        $('#ajax-remote-example .typeahead').typeahead({
            hint: true,
            highlight: true,
            minLength: 1
        }, 
        {
            name: 'cities',
            displayKey: 'CityName',
            source: remote_cities.ttAdapter(),
        });

數據爲:

[{"Id":1,"ProvinceName":"廣東省","CityName":"廣州市"},{"Id":2,"ProvinceName":"山東省","CityName":"濟南市"},{"Id":3,"ProvinceName":"陝西省","CityName":"西安市"},{"Id":4,"ProvinceName":"北京市","CityName":"北京市"},{"Id":5,"ProvinceName":"廣西自治區","CityName":"南寧市"},{"Id":6,"ProvinceName":"江蘇省","CityName":"南京市"}]

文件結構爲:

clipboard.png

效果圖爲:

clipboard.png

看到這裏應該有很多人有疑問吧?爲何輸入「南」字,雖然與「南」相關的數據都有匹配到,可是全部數據都出來了?這是爲何呢?
答案有點繞,首先,咱們要清楚一點,remote的方法是當你觸發事件後,纔想遠程及時獲取數據的,可是示例3所有用到的是前端的東西,只是模擬從遠程拿取數據,並無從真正的服務器上面獲取,因此結果就是顯示全部數據(個人錯!哈哈哈),解決方法就是:在服務端加多一個正則加以過濾,只有匹配到的纔拿下來。雖說前端也是能夠作過濾的,可是儘可能不要把沒必要要的數據下載下來。

有些同窗可能會問了,示例2和示例3的數據匹配方式好像不一樣耶?爲何同一個庫示例2匹配只從頭開始,而示例3則是任意文字匹配呢?
答案:由於在typeahead裏面prefetch和remote封裝的方法不一樣。詳情能夠查看typeahead裏面的源碼。

接口:
name —— 數據集的名字。
source —— 規定包含查詢時要顯示的值的數據源。值的類型是 array,默認值是 [ ]。
items —— 規定查詢時要顯示的條目的最大值。數據類型是 number,默認值是 8。
highlighter —— 用於自動高亮突出顯示結果。帶有一個單一的參數,即具備 typeahead 實例範圍的條目。數據類型是 function。默認狀況下是高亮突出顯示全部默認的匹配項。
minLength —— 推薦引擎開始渲染所須要的最小字符。默認爲 1 。
hint —— 默認爲 true,會自動補全第一個匹配的元素,設置爲 false 時,typeahead 將不會補全 .
display - 對於推薦對象,決定用何種字符串表示,並將會在某個輸入控件選擇後使用。其值能夠是關鍵字符串,或者是將推薦對象轉換爲string的函數。默認爲 value.
$('.typeahead').typeahead('destroy');移除typeahead功能,並將 input 元素的狀態重置爲原始狀態。
$('.typeahead').typeahead('open');打開typeahead下拉菜單。
$('.typeahead').typeahead('close');關閉typeahead的下拉菜單。
var myVal = $('.typeahead').typeahead('val'); 返回typeahead的當前值,該值爲用戶輸入到 input 元素中的文本
$('.typeahead').typeahead('val', myVal);設置typeahead的值,要來替代 jQuery#val 函數。

實屬原創,若有錯誤,煩請指教!

相關文章
相關標籤/搜索