49

他のライブラリに依存しないjavascriptオートコンプリートライブラリはありますか?

私は余分な光を保つ必要があるモバイルアプリを作っているので、jQueryなどを使用していません。

4

6 に答える 6

9

オートコンプリート スクリプトの核となるのは、用語の辞書への ajax 呼び出しです。

あなたのモバイル アプリケーションには既に ajax 関数が含まれていると思います。基本的に、入力タグ、ajax 呼び出しをトリガーするキーアップ イベント ハンドラー、および応答を収集する div で必要なものはすべてです。

[更新] コメントに基づいて、John Resig のブログからのいくつかの参照:

http://ejohn.org/blog/revised-javascript-dictionary-search/

http://ejohn.org/blog/jquery-livesearch/

于 2012-07-10T01:57:03.823 に答える
0

JSON 要求をサーバーに送り返し、Python コードを使用してオートコンプリートを実行することで、これを 1 回行いました。少し遅かったですが、大量のデータを送信する手間が省けました。

于 2012-07-10T00:06:42.257 に答える
0

私は先日これを調査していましたが、私のソリューションは元々、次のような ES6 ソリューションのようなものでした。

return this.data.filter((option) => {
    return option.first_name
        .toString()
        .toLowerCase()
        .indexOf(this.searchTerms.toLowerCase()) >= 0
})

しかし、それに関する問題は、ネストされたデータのフィルタリングを処理するのに十分な堅牢性がないことです。this.data次のようなデータ構造を持つフィルタリングであることがわかります。

[
    { first_name: 'Bob', },
    { first_name: 'Sally', },
]

this.searchTerms検索用語 と の両方を小文字にした後に に基づいてフィルタリングすることがわかりますがoption.first_name、厳密すぎて を検索できませんoption.user.first_name。私の最初の試みは、次のようにフィルター処理するフィールドを渡すことでした。

this.field = 'user.first_name';

this.field.split('.')しかし、これには、フィルター関数を動的に生成するようなものを処理する野蛮なカスタム JavaScript が含まれます。

代わりに、以前使用していた と呼ばれる古いライブラリを思い出しました。このライブラリはfuse.js、先ほど呼び出したものに対する任意のネストのケースを処理するだけでなくthis.field、定義されたしきい値に基づいたファジー マッチングも処理するため、うまく機能しています。

こちらをご覧ください: https://fusejs.io/

[編集注]: この質問が no-external-library を探していることは理解していますが、隣接する価値があるため、この投稿をここに残しておきたいと思います。「その」ソリューションになることを意図したものではありません。

これが私が現在それを使用している方法です:

import Fuse from 'fuse.js';

const options = {
    threshold: 0.3,
    minMatchCharLength: 2,
    keys: [this.field],
};

const fuse = new Fuse(this.data, options);

this.filteredData = fuse.search(this.searchTerms);

それをよりよく理解するには Fuse のドキュメントを読む必要がありますが、基本的には、new Fuse()フィルタリングするデータとオプションを使用してオブジェクトが作成されることがわかります。

このkeys: [this.field]部分は、検索するキーを渡す場所であり、それらの配列を渡すことができるため、重要です。たとえば、 でフィルタリングできthis.dataますkeys: ['user.first_name', 'user.friends.first_name']

私は現在これを Vue JS で使用しているため、インスタンスwatch関数内に上記のロジックがあるため、変更されるたびにそのロジックが実行され、オートコンプリート コンポーネントのドロップダウン リストに配置されてthis.searchTerms更新されます。this.filteredData

また、この質問が外部ライブラリなしで具体的に述べていることに気付きましたが、Vue JS または React JS で ES6 オートコンプリートを作成するたびにこの質問を見つけるので、とにかく投稿します。厳密または緩いあいまい一致を持ち、任意にネストされたデータをサポートすることは非常に価値があると思います。Webpack バンドル アナライザーに基づいており、fuse.js4.1kb gzip 圧縮されているため、「すべての」クライアント側フィルタリングのニーズをサポートできることを考えると、非常に小さいです。

外部ライブラリを使用する能力が限られている場合は、私の最初のコード例を検討してください。option.first_nameデータ構造が静的である場合に機能し、検索フィールドを可変にしたいoption[this.field]場合 (つまり、オブジェクトが常にフラットである場合)などに簡単に変更できます。

リストを変数化して検索することもできます。次のようなことを試してください:

const radicalFilter = ({ collection, field, searchTerms }) => {
    return collection.filter((option) => {
        return option[field]
            .toString()
            .toLowerCase()
            .indexOf(searchTerms.toLowerCase()) >= 0
    })
}

radicalFilter({
    collection: [{ first_name: 'Bob' }, { first_name: 'Sally' }],
    field: 'first_name',
    searchTerms: 'bob',
})

過去数年間の私の経験に基づくと、上記のサンプルは非常に優れたパフォーマンスを発揮します。コンポーネントで10,000 レコードをフィルタリングするために使用しましたがreact-table、汗をかきませんでした。余分な中間データ構造は作成されません。それは単にArray.prototype.filter()あなたの配列を取り、一致した項目を持つ新しい配列を返すだけです.

于 2019-10-18T17:21:49.270 に答える