フロントエンドも片手の指の本数以上の年数を経験し、さらにアイポーなどの登場する前から開発もしていれば、使用しているライブラリで痛い目にあうことなんぞあるわけですが。
最近はまー、ブラウザもよくなっているし、ライブラリなんて「ステキーvさくっといけるわー」を連発しても足りないほどのよさなので。
そう、「ライブラリを信じすぎると痛い目に会う」という事態を忘れていましたです、ハイ。
実際にはこのようにサクッと食らっていたんですが、「自分とこのjsが悪いんのんんん!????」と思って微調整をしておりました。
今回、痛い目を見たのは
Modernzr「css hyphens」
の検知部分。
症状
設計したサイトで久しぶりにハッシュ付きURLでの遷移が発生。
1) で、URL入れて遷移。
おりょ? 遷移しない!
PCでいくつかのブラウザで試したものの、どれも同じ。
うむむーーーーと思い、昔も何かの組み合わせで、ハッシュで指定したところに移動しなかったなー。。。
という、昔の経験が思い出され、今組んでいるJSでの処理と移動が相性でも悪いのかも、ハッシュでの移動がぜんぜん動いていないしな、、、
という事象の発生と思い込み。
2) 動かないなら動かしてしまえ、ブラウザさん。
あまり調査をしないでの対処療法はよろしくないんですが。
時間もないし、ないし(重要なことなので2回書きました。)、で対処療法へ。
要はURLがハッシュ付きなら、スクロールを強制的にそこまで動かせばいいので。
if(location.hash){
// ハッシュで指定されたDOM取得して、ページ上での位置を算出
// そこまでスクロール移動
}
の考え方でクリアできます。
loadタイミングで仕掛けることにして、発火タイミングを調整しました。
移動ががたつくので、気に入らないけど一旦fix。
3) ところが、別なページではまったく動かない!
ので、きちんと調査、の運びとなりました。
原因
「動いていない」と思い込んでしまったのですが、
強制的な移動処理の発火を遅らせてみると、
・ 想定の位置に移動
・ 次に、ページトップへ戻る
・ 想定の位置に移動
していることがわかりました。自作のJSを疑ってみるも、該当するscroll系の処理は見つからず。
なので、すべてのjsを一旦外して、一つずつ取り込みをしたところ、
Modernzr
を設定すると、”ページトップ”への表示が強制されました。
そこで内容をチェック。
scroll系の発見はできず。まあ、当たり前だよなーと。スクロールして検知するってなんだろ?なので、さくっと次の調査に。
で、次に探したのはfocusメソッド系。
この辺りは経験値が生きるというか、移動しようとしないで移動しちゃうぜーという動きに関与するメソッドのあたりは付けられます。
focusするということは、そこにユーザーを誘導したいわけなので、
今見ているところに該当物がなければ、そこまでスクロール移動しちゃわけです。
そこで発見。minifyしたファイルを解凍したので見えにくいのですが
function l(n) {
try {
var i, o = a("input"),
r = a("div"),
s = "lebowski",
l = !1,
u = t.body.firstElementChild || t.body.firstChild;
r.innerHTML = s + n + s, t.body.insertBefore(r, u), t.body.insertBefore(o, r), o.setSelectionRange ? (o.focus(), o.setSelectionRange(0, 0)) : o.createTextRange && (i = o.createTextRange(), i.collapse(!0), i.moveEnd("character", 0), i.moveStart("character", 0), i.select());
try {
e.find ? l = e.find(s + s) : (i = e.self.document.body.createTextRange(), l = i.findText(s + s))
} catch (d) {
l = !1
}
return t.body.removeChild(r), t.body.removeChild(o), l
} catch (d) {
return !1
}
}
さて、ここの関数をさっと見ると
・ input要素作っている
・ 要素をbodyの最初に挿入している
・ 途中でfocusメソッド実行している
のが見えます。後で要素が削除されるので起こった後は「なんでや」になりますけど、
これで”ページトップ”へ行く謎が解けるのです。
実際、このメソッドの中身を動かさなければ、Modernzrを実行しても所定の要素に遷移できました。
前後の呼び込みの様子からキーワードでググってみると、これが「css hyphens」の検知で使われている模様まで判明。
昔からの構成らしく、珍しくもないようで。
上記の検知部分を排除したライブラリを再作成すると、問題なし!
今まで組み込んでいたけど、発生がサイトの構成にも関係するので、毎度ぶち当たらない問題でございました。
さすがにライブラリの中を細かく最後まで追いませんでしたが、
1) input要素を突っ込んで、そこへ移動&フォーカス
2) 選択状態にして、ページ上で選択している部分の次に判定要素を持ってくる
ことで、より速い判定をしているということなのかな、と。
input要素は確かに後から削除しているけど、残念である。フォーカスしたことは戻らない。