Qiitaの狭幅レイアウト時のモーダル検索バーにフォーカスするユーザースクリプト

![qsh.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/b65e0b3f-105b-a2f7-38a6-6f8216c4e46c.gif)

:smile: 

![ghsb.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/e77f6ecf-2b6c-1172-2cb3-db109ee649a6.gif)

:angry: :angry: 

![qhsg.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/58cfc3b4-2789-b91e-77ff-83b5c1fee7de.gif)


:smile: :smile: :smile:

トップページだとちゃんとfocusされているのに、他では効かずに２個めの画像の罠にひっかかる。

# 動作検証環境

* Windows 7
* Firefox 59
* Tampermonkey v4.6.5709


# コード

```Qiita-focus-on-search-modal.user.js
// ==UserScript==
// @name         Qiita focus on search modal
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  検索バーポップアップ時にフォーカスする。(ホーム以外でも)
// @author       khsk
// @match        https://qiita.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const button = document.querySelector('.st-Header_searchButton');
    const input  = document.querySelector('.st-Header_searchModalInput');
    if (!button || !input) {
        console.log('ナイデース');
        return;
    }
    button.addEventListener('click', () => {
        // display none の間はfocusが効かないので、Qiita側のEventで表示されるのを待つ。(予想)
        setTimeout(() => {
            input.focus();
        },0);
    });
})();
```

# コード予想

モーダル自体のHTMLがほぼ共通でこんなの

```html

// 虫眼鏡
<div class="st-Header_searchButton"><span class="fa fa-search"></span></div>

// モーダル
<form class="st-Header_searchModal" action="/search" method="get">
    <input class="st-Header_searchModalInput" autocomplete="off" placeholder="キーワードを入力" name="q" required="" type="text">
</form>
```

で、トップページのJavaScriptがこれ

```js
 f('div', {
      class: 'st-Header_searchButton',
      onclick: t.openSearchForm
    }, 

// ～～～

 f('input', {
      class: 'st-Header_searchModalInput',
      type: 'text',
      autocomplete: 'off',
      placeholder: r('searchPlaceholder'),
      value: n.searchQuery,
      name: 'q',
      required: !0,
      oninput: function (e) {
        return t.setQuery(e.target.value)
      },
      onupdate: function (e) {
        n.isSearchFormOpen && e.focus()
      }
    }))))
  },

```

虫眼鏡をクリックすると、`openSearchForm`で`isSearchFormOpen`が`!0`になって、`onupdate`が走って`focus`される、かな。

対して、記事画面がこう

```js
})), f.default.createElement("div", {
                        className: "st-Header_searchButton",
                        onClick: this.openSearchForm
                    }, f.default.createElement("span", {
                        className: "fa fa-search"
                    }))), this.renderHeaderEnd(), f.default.createElement("div", {
                        className: "st-Header_overlay",
                        onClick: function() {
                            t.closeCommunityDropdown(), t.closeHomeDropdown(), t.closeNotification(), t.closeProfileDropdown(), t.closeSearchForm(), t.closeRealmSelector()
                        }
                    }), f.default.createElement("form", {
                        className: "st-Header_searchModal",
                        action: "/search",
                        method: "get"
                    }, f.default.createElement("input", {
                        className: "st-Header_searchModalInput pl-1",
                        type: "text",
                        autoComplete: "off",
                        placeholder: I18n.t("js.views.new_header.searchPlaceholder"),
                        name: "q",
                        required: !0
                    }))))
                }
            }, {
```

浅学なのでなんとも言えませんが、一見`onChange`がないし、
`openSearchForm`で`!0`にされた`isSearchFormOpen`も`focus()`とは絡みそうになさそうなので、環境依存で動かないというよりは実装されてない可能性もあるかも…？

しかしどうしてこう実装が異なるのかな？
記事画面はReactらしいが…とここで

[新QiitaでReactをやめてhyperappを採用した背景 - Qiita](https://qiita.com/yuku_t/items/2839e57a1933507f36b4)

でトップページだけhyperapp製になったんだと思いだした。
なので現在は少なくともhyperappとReactが並行稼動しているわけで、見た目がすごく同じでも動きが異なるのにも納得できた。



# `setTimeout`のわけ(参考)

コメントにある通り、`display: 'none'`には`focus()`できない説
[PHPマニュアルから関数をコピーするボタンを追加するユーザースクリプト - Qiita](https://qiita.com/khsk/items/b78315e7024107008956) (node選択もできない)
[html - Why changing visibility/display on focus does not work? - Stack Overflow](https://stackoverflow.com/questions/21351476/why-changing-visibility-display-on-focus-does-not-work)

と、イベント中にfocusイベント起こせない説がある？(こっちはonFocusでfocus()とは無関係？)
[【js】firefoxでfocusイベントが動かない - Qiita](https://qiita.com/gamushiro/items/4db8c91603b7c165d909)