jQuery コードについて質問です。

以下コードでクリックした時にanimationでコンテンツを表示して、更にページアンカー機能を付けたいのですが、うまく動作してくれません。
コールバック関数の入れ子には限界があるのでしょうか?またはコードの書き方に問題があるのでしょうか?
何か少しでもヒントになる情報をお寄せ下さい。宜しくお願い致します。

(jquery1.3.2)

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2010/09/22 12:46:34
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:y-kawaz No.1

回答回数1422ベストアンサー獲得回数226

ポイント60pt

入れ子の数とかは別に問題ないですが、コールバック関数を入れ子にする場合は 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 の使い方しか直しておらず、それ以外のコードには目を通してないので他にバグがった場合は知りません。

  • id:mune0628
    $('#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;
    });


    <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>
  • id:Cherenkov
    中途半端なコードでは回答者の手間が増えデバッグし辛いです。
    最低限不具合が再現するコードを提示するべきです。
    質問文では何をしたいのかよくわからないので補足したほうがいいです。
  • id:rouge_2008
    HTML構造が不明確なので、コードをどのように書くと正常に動作するのか分からないと思います。
    「$("#"+targetLink).text()」という事は、リンク先(?)の表示させたいコンテンツは「id="contents1"」等が指定されているのですか?
    それから、コンテンツが存在しなかった場合、rootPathが定義されていないのでエラーが発生します。
  • id:mune0628
    >y-kawazさん
    ご指摘頂いたコードを修正した所、意図した表示になりました!
    変数について大変勉強になりました。ありがとうございます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません