[JavaScript] iOS Safari でインクリメンタルサーチを実装するのにイベントでひとクセあり

Web ページにインクリメンタルサーチを実装するときに、つまづいたところ、解決方法を書きます。

検索テキストボックスに文字を入力していくたびに検索結果がどんどん変わっていくものです。応答速度が早ければ便利ですね。

最低限必要なコンテンツは以下のとおりです。

<p class="search">
<input type="text" name="search" placeholder="検索文字を入力">
<ul class="results" data-selected="0">
    <li class="selected">あああ商店</li>
    <li>いいい商店</li>
</ul>
</p>

ul は初期表示では非表示「display:none」としておきます。細かいテクニックですが、まず ul.results はページ内に浮かせます。ここで絶対位置「position:absolute」を指定し、p.search から浮かせるようにします。これの実現には、p.search を相対指定「position:relative」にする必要があります。初期値「position:static」のままだと、さらに親の要素で static ではない要素にくっつくことになります。こういった制御は JavaScript を使うことになりますが、幅などの細かいスタイルについては JavaScript で付与することになります。

さて核心になりますが、検索ボックスの内容変更のたびに検索を行う機能について、テキストボックスのイベントを使用します。まずはキー入力の「onkeyup」を使用します。

const txt = document.getElementsByName('search')[0];
var evt = function (_event) {
//インクリメンタル検索処理
} txt.addEventListener('keyup', evt, false);

インクリメンタル検索の具体的処理については、サイトの性質や環境によって実装方法が多いため、省略します。ランサーサイトで個別にご相談ください。

この処理、PC環境では正常に機能します。keyupがきちんと拾ってくれています。正常に動かないのはスマホで、特に漢字変換関係で引っ掛かります。

たとえば「アイウエオ」を入力しようとすると、「あいうえお」のkeyupイベントが発生します。次にキーパッドで「アイウエオ」を選択してもkeyupは動きません。「商店」を検索したいときでも、「しょうてん」でkeyupが動き「商店」の漢字を確定させたときにはkeyupは動きません。

どうすればよいかというと、変換確定時に呼ばれる「oncompositionend」を使います。

txt.addEventListener('compositionend', evt, false);

keyupと並べて使っても問題無いと思います。これで確定後のテキストの中身を使うことができます。