スムーズスクロールをさせているときに、外部ページからハッシュタグつきで飛んできた時
ページ内要素の読み込みが終わってからスクロールさせないと、変な位置に止まってしまう。
ほかにも画像ロードが終わるまで待つ処理は結構使うことがあるので、スムーズスクロール処理の内容と一緒にメモしておく。
エラー処理とかは特にいれていません。
// window
var $window = $(window);
// body&html
var scrollElement = 'body,html';
// window load event
$window.on('load', function () {
// URLにハッシュがついていれば画像ロードをまつ
var urlHash = location.hash;
if (urlHash) {
var $target = $(getTarget(urlHash));
var promise = preload();
// 画像ロード終了後にスクロールを実行
promise.then(function () {
scrollToAnchor($target);
});
}
});
// 画像の先読み関数。promiseを返す。
function preload() {
var $images = $('img');
var promises = [];
var retDefer = $.Deferred();
$images.each(function (index, item) {
var defer = $.Deferred();
if (isLoaded(item)) {
// ロード済みなので待たない
defer.resolve();
} else {
// ロードしてなければロード
// ロード処理後のコールバックでresolve
// ロードできなくても無視する
$(item).load($(item).attr('src'),function(){
defer.resolve();
});
}
promises.push(defer.promise());
});
$.when.apply(null, promises).done(function () {
retDefer.resolve();
});
return retDefer.promise();
}
// load check
function isLoaded(element) {
// IE以外
if (element.complete) {
return true;
}
// IEは画像の幅を取得することでロード済かどうかを判断
if (typeof element.naturalWidth !== 'undefined' && element.naturalWidth > 0) {
return true;
}
return false;
}
// scroll to anchor
function scrollToAnchor($target) {
// スクロールするスピード
var speed = 400;
// スクロールするポジション
var position = 0;
position = $target.offset().top;
$(scrollElement).animate({'scrollTop': position}, speed, 'swing');
}
// get href of clidked link
function getTarget(href) {
return href === '#' || href === '' ? 'html' : href;
}
参考にしたサイト
- 先読みする画像全ての読み込みが完了したら処理をする(上級)