株式会社グローバルゲート公式ブログ

外部ページの取得と簡単な検索システムをJavascriptで作る

こんにちは。株式会社グローバルゲートのモーリーです。

6月16日をもってInternet Explorerのサポートが終了しました。
ブラウザの中でもWindowsにプリインストールされているため多くの方が利用していましたが、独自仕様が多くWeb技術者を長年苦しめたブラウザでもあります。

IEの独自仕様がWebの標準規格としてフィードバックされたりインターネットの普及に一役買ったりもしましたが、Webに関わる技術者のほとんどは恨みのほうが多いでしょう。特にCSSの解釈は不完全なものが多く、苦しんだWebデザイナーも多いです。

もっとも、現在主流のブラウザはほとんどChromiumベースとなってしまいましたので、競争がなくなったことで技術の発展が滞ったり、Chromiumに脆弱性がみつかるとほぼすべてのブラウザに影響するなど、問題がないわけではありません。競合であるFirefoxの進歩や第3のブラウザの登場も期待したいところです。
Opera?いいブラウザでしたね…

墓まで建てられる始末…。R.I.P.

さて、今回は外部ページのデータを取得し、簡単な検索システムをJavascriptだけで作るということをやってみようと思います。 
 
検索システムとなるとデータをデータベースに登録してPHPなどサーバーサイドのプログラムで検索して表示させて...と少々手間がかかる仕事となるのですが、簡易なものならJavascriptだけで作成することができます。

Step1. 外部ページの取得 
Step2. 取得したページの内容から必要データの抽出 
Step3. 検索機能の構築 

という流れで行います。 
 
実際に動く例 
検索はAND検索、検索にヒットしない場合は全データを表示するということにしています。 

fetchAPIで外部ページの取得 

検索対象となるデータを別ページで用意している場合、まずは其のページを取得する必要があります。 
従来はjQueryによるAjaxやaxiosというライブラリを使用する方法が王道でしたが、現在はfetchAPIという機能があるのでたった1行で外部ページを取得することができます。 

fetch('取得したいページのURL') 

この1行で指定ページを取得できます!超簡単! 
このfetchという機能もInternet Explorerでは使うことができなかった機能です。

取得したページから必要データの抽出 

fetchで取得した結果はtext()という関数によって文字列として取得できます。 
その文字列をDOMとして解釈することにより、querySelector()のような関数で必要なタグのみを取得することができます。 
 
たとえば、#searchTarget tableがほしいデータとすると以下のようにすればtableのみを取得することができます。 

const html = await data.text() 
const dom = new DOMParser().parseFromString(html, 'text/html'); 
const domTarget = dom.querySelector('#searchTarget table') 

今回はVue.jsを併用し、table内のデータをJSONとして保持して利用してみます。 

domTarget.querySelectorAll('tbody tr').forEach(function (elem, i) { 
    const obj = [] 
    vm.data.push(obj) 
    elem.querySelectorAll('td').forEach(function (elem2, i2) { 
        const item = { 
            name: vm.index[i2], 
            value: elem2.innerHTML 
        } 
        vm.data[i].push(item) 
    }) 
}) 

検索機能の構築 

検索文字列を入力して「検索」というボタンを押して検索結果を表示させるというのが普通の動きですが、今回は文字入力が終わった直後リアルタイムに検索結果を表示させるインクリメンタルサーチを実装してみたいと思います。 
 
検索文字列を入力するフォームにinputイベントをバインドします。 

<input type="text" class="form-control" :id="'search-' + i" v-model="query['query-' + i]" v-on:input="searchExec"> 

そして入力内容からデータオブジェクト内を検索します。 
この書き方はいろいろバリエーションがあると思うので、一例と思ってください。 

searchExec() { 
    const vm = this; 
    vm.$set(vm, 'result', []) 
    vm.data.forEach(function (elem, i) { 
        let flg = []; 
        Object.keys(vm.query).forEach(function (i2) { 
            const index = i2.replace('query-', '') 
            flg.push(elem[index].value.indexOf(vm.query[i2]) !== -1) 
        }) 
        if ( 
            flg.every(function (val) { 
                return val 
            }) 
        ) { 
            vm.result.push(elem); 
        } 
 
    }) 

ソース全文はgithubをご参照ください。 

まとめ

ということで、今回はJavascrptだけで簡単な検索機能を作ってみました。 
たくさんの商品や店舗などを紹介する場合、単に羅列するだけよりも便利に使うことができるのではないでしょうか。 

検索する対象データの分量が多すぎたり複雑な形式の場合この方法は使えないのですが、サーバー側のプログラムなしで検索機能を導入できればコスト削減や管理の簡素化という点で利点があります。
このような機能の導入をご要望の場合はぜひグローバルゲートまでご相談ください。

【関連記事】

ご相談・お問い合わせ

当社サービスについてのお問い合わせは下記までご連絡下さい。

お電話でのお問い合わせ

06-6121-7581 / 03-6415-8161