非同期遷移なサイトにハッシュ(#)を含むURLでアクセスされた時、目的の要素までスクロールするという処理を自分で実装しないといけないことがある。例えば、http://example.com/aaa/からhttp://example.com/bbb/#cccに非同期遷移した場合、当たり前だが、ブラウザはid=”ccc”の要素までスクロールしない。そこで、今回は自分で目的要素までスクロールする処理を考えてみる。
自分で実装と言ってもそこまで難しくはなく、スクロールするだけなら単にAPIで用意されている、elementのscrollIntoViewメソッドを呼べばいい。つまり、ハッシュの文字列を得て、該当の要素のscrollIntoViewメソッドを呼ぶ。
function scrollIntoViewOf(hash) { var element = document.getElementById(hash); if(element === null) { return; } element.scrollIntoView(); }
もちろんinnerHTMLなどで非同期で取得した要素に切り替えた後に呼ばないとスクロールしない。しかし、切り替えた要素にimg要素が含まれている場合、img要素のsrc属性は非同期で呼ばれるため、正しい位置にスクロールしてくれない。画像が読み込まれる前と読み込まれた後では要素の高さが違うためである。つまり、画像が全て読み込まれた後にscrollIntoViewを呼び出す必要がある。そこで、前回の記事で紹介した「全ての画像を読み込んでから処理を実行するimagesLoadListener」が使える。
function scrollIntoViewOf(hash, imagesLoadListener, replacedElement) { var element = document.getElementById(hash); if(element === null) { return; } imagesLoadListener(replacedElement, function() { element.scrollIntoView(); }); }
これで正しい位置までスクロールしてくれるはずだ。