トップページだとちゃんとfocusされているのに、他では効かずに2個めの画像の罠にひっかかる。
動作検証環境
- Windows 7
- Firefox 59
- Tampermonkey v4.6.5709
コード
// ==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がほぼ共通でこんなの
// 虫眼鏡
<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がこれ
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
される、かな。
対して、記事画面がこう
})), 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
でトップページだけhyperapp製になったんだと思いだした。
なので現在は少なくともhyperappとReactが並行稼動しているわけで、見た目がすごく同じでも動きが異なるのにも納得できた。
setTimeout
のわけ(参考)
コメントにある通り、display: 'none'
にはfocus()
できない説
PHPマニュアルから関数をコピーするボタンを追加するユーザースクリプト - Qiita (node選択もできない)
html - Why changing visibility/display on focus does not work? - Stack Overflow
と、イベント中にfocusイベント起こせない説がある?(こっちはonFocusでfocus()とは無関係?)
【js】firefoxでfocusイベントが動かない - Qiita