以下コードでクリックした時にanimationでコンテンツを表示して、更にページアンカー機能を付けたいのですが、うまく動作してくれません。
コールバック関数の入れ子には限界があるのでしょうか?またはコードの書き方に問題があるのでしょうか?
何か少しでもヒントになる情報をお寄せ下さい。宜しくお願い致します。
(jquery1.3.2)
入れ子の数とかは別に問題ないですが、コールバック関数を入れ子にする場合は this が何を指しているかをキチンと把握していないといけません。多分それかなーと思ってthisの使い方だけチェックしたらやはり問題がありました。
とりあえず、コードが見にくかったので整形してみました。
$('#menu a').click(function(){ $('h1#title').animate( { marginTop: '0' }, 1000 , function(){ // contentをスライド・イン $('#content').slideToggle( 1000 , function(){ //SCROLL HANDLING //get the href value var whereTo = $(this).attr("href"); var targetLink = whereTo.substring(1); //remove hash //if there is a div on this page where id = whereTo, then scroll to it if($("#"+targetLink).text() != ''){ $.scrollTo( $("#"+targetLink), 1000, { axis: 'y', easing: '', onAfter: function(whereTo) { setTimeout( function() { window.location.hash = targetLink; hash = window.location.hash; }, 100 ); } } ); } else{ window.location = rootPath + whereTo; } } ); } ); return false; });
このコードでは whereTo という変数を作るために this が1箇所使われてます。
質問者さんはこの this にクリックされた a タグが入っていて欲しいんだと思いますが、この this には一番内側の $('#content') のエレメントが入ってる筈なので、それで動かないんだと思います。
このような場合は this を一度別の変数に入れておくのが常套手段です。以下のように直せば動くんじゃないでしょうか?
$('#menu a').click(function(){ var clicked_a = this; $('h1#title').animate( { marginTop: '0' }, 1000 , function(){ // contentをスライド・イン $('#content').slideToggle( 1000 , function(){ //SCROLL HANDLING //get the href value var whereTo = $(clicked_a).attr("href"); var targetLink = whereTo.substring(1); //remove hash //if there is a div on this page where id = whereTo, then scroll to it if($("#"+targetLink).text() != ''){ $.scrollTo( $("#"+targetLink), 1000, { axis: 'y', easing: '', onAfter: function(whereTo) { setTimeout( function() { window.location.hash = targetLink; hash = window.location.hash; }, 100 ); } } ); } else{ window.location = rootPath + whereTo; } } ); } ); return false; });
修正点は変数 clicked_a を導入しただけです。
ちなみに this の使い方しか直しておらず、それ以外のコードには目を通してないので他にバグがった場合は知りません。
コメント(4件)
$('h1#title').animate({marginTop: '0'}, 1000 ,
function(){
// contentをスライド・イン
$('#content').slideToggle(1000 ,
function(){
//SCROLL HANDLING
//get the href value
var whereTo = $(this).attr("href");
var targetLink = whereTo.substring(1); //remove hash
//if there is a div on this page where id = whereTo, then scroll to it
if($("#"+targetLink).text() != ''){
$.scrollTo( $("#"+targetLink), 1000, {axis: 'y', easing: '',
onAfter:function(whereTo) {
setTimeout(function() {
window.location.hash = targetLink;
hash = window.location.hash;
}, 100);
}} );
} else{
window.location = rootPath + whereTo;
}
});
});
return false;
});
<h1 id="title">タイトル</h1>
<div id="menu">
<ul>
<li><a href="#contents1">contents1</a></li>
<li><a href="#contents2">contents2</a></li>
<li><a href="#contents3">contents3</a></li>
<li><a href="#contents4">contents4</a></li>
<li><a href="#contents5">contents5</a></li>
</ul>
最低限不具合が再現するコードを提示するべきです。
質問文では何をしたいのかよくわからないので補足したほうがいいです。
「$("#"+targetLink).text()」という事は、リンク先(?)の表示させたいコンテンツは「id="contents1"」等が指定されているのですか?
それから、コンテンツが存在しなかった場合、rootPathが定義されていないのでエラーが発生します。
ご指摘頂いたコードを修正した所、意図した表示になりました!
変数について大変勉強になりました。ありがとうございます。