【jQuery】クリックで非表示領域を表示。その際に、アンカーリンクで非表示領域内にスクロール!

アンカーリンクのボタンをクリックして、slideUp('fast');css('display','none') の中にあった アンカーリンク先 にスクロールslideUp('fast');

解決方法は一番下に書きました。

まずは原因の話から

やりたいこと

通常のクリックで開く動作

$('#bodyG').css('display','none');
$('#portfolio').click(function() {
$('#bodyG').slideUp('fast');
});

スムーススクロール

$(function(){
// #で始まるアンカーをクリックした場合に処理
$('a[href^=#]').click(function() {
// スクロールの速度
var speed = 400; // ミリ秒
// アンカーの値取得
var href= $(this).attr("href");
// 移動先を取得
var target = $(href == "#" || href == "" ? 'html' : href);
// 移動先を数値で取得
var position = target.offset().top;
// スムーススクロール
$('body,html').animate({scrollTop:position}, speed, 'swing');
return false;
});
});

参考:http://kyasper.com/jquery-tips/

上記2つの挙動を1回のクリックで同時に処理を走らせようとしました。

しかし、エラーが出ました。

こんなのや

$('#bodyG').css('display','none');
$('#portfolio').click(function() {
$('#bodyG').slideUp('fast');
var speed = 400; // ミリ秒
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top;
$('body,html').animate({scrollTop:position}, speed, 'swing');
return false;
});

こんなの(display:noneを表示してからスクロール位置を求めようとしました。。。)

$('#bodyG').css('display','none');
var speed = 400; // ミリ秒
var myPromise = $.when($('#bodyG').slideUp('fast'));
$('#portfolio').click(function() {
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
myPromise.done(function() {
var position = target.offset().top;
$('body,html').animate({scrollTop:position}, speed, 'swing');}
);
return false;
});

参考:jQueryで、順番に実行が出来る .when() から .done() が便利だったのでメモ

かなと思いましたが、これだと、
エラー
「offset().top is null or not an object error」が出て
処理が最後まで行きません。

つまり、
var position = target.offset().top;
でエラーが発生しているのですが、

問題の原因は以下でした。
「offsetで値を求める際に、display:none を設定した場合、top, left ともに 0 となります。」

注意: jQueryはhidden要素のオフセットの座標の取得、 またはbody要素に設定されたborder、margin、paddingを考慮しての位置計算をサポートしません。 visibility:hiddenが設定された要素の座標の取得が可能である一方、 display:noneはレンダリングツリーから除外されるため、未定義(undefined)のpositionとなります。

http://js.studio-kingdom.com/jquery/css/offset

 

解決策

Stack Overflowで解決策を見つけました!!
解決策はこちら↓

$('#portfolio').click(function(e){
e.preventDefault();
var href = $(this).attr('href');
$('#bodyG').slideUp('fast', function() {
window.location = href;
});
});

xdazzさん、ありがとうございます!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です