2017-02-24 16 views
1

私はJQuery(C#)の新機能で、ここで間違っていることを見ることはできません。リファクタリング後にJQuery関数が正しく機能しない

私はハンバーガーメニューを切り替える次のJQueryを持っています。また、調子の効き目を入れて、Bodyへのスクロールを防ぎます。ハンバーガーは3本の水平線からXまでアニメートします。最初のJQuery(下)ではこれがうまくいきます。しかし、私はこれを洗練して、私のコードを2番目のJQueryにクリーンアップしようとしています。しかし、私がこれを行うと、ハンバーガーから離れて意図したように動作し、Xにはもはやアニメーション化されません。なぜなら、私の初心者のJQueryの目には、

また、私はまた、次のコード2行をしても、このような機能で必要とされるかどうかを知るのが大好きだ初心者のように:

e.preventDefault(); 

event.stopPropagation(); 

jQueryの(作品):

jQuery(document).ready(function() { 
    jQuery('#toggle-nav').click(function (e) { 
      event.stopPropagation(); 
      jQuery(this).toggleClass('active'); 
      jQuery('.menu ul').toggleClass('active'); 
      jQuery('.hamburger ul').toggleClass('active'); 
      jQuery('.dimmer').toggleClass('active'); 
      jQuery('body').toggleClass('no-scrolling'); 

      e.preventDefault();    
    }); 
}); 

はJQuery (動作しない):

jQuery(document).ready(function() { 
    jQuery('#toggle-nav').click(function(e) { 
    toggleNav(); 

    function toggleNav() { 
     event.stopPropagation(); 
     jQuery(this).toggleClass('active'); 
     jQuery('.menu ul').toggleClass('active'); 
     jQuery('.hamburger ul').toggleClass('active'); 
     jQuery('.dimmer').toggleClass('active'); 
     jQuery('body').toggleClass('no-scrolling'); 

     e.preventDefault(); 
    } 
    }); 
}); 
+3

あなたは 'event.stopPropagation()'を使用すべきではありません。 'e.stopPropagation()'でなければなりません。また、イベントハンドラ自体で定義されている新しい関数にコードを移動すると、その関数がクリックするたびにその関数が再定義されるため、愚かなように見えます。 –

+0

答えがありがとうございました。私がやっていたこと。 – Damo

答えて

2

あなたにはいくつか問題があります。あなたは、clickイベントの内部で関数を定義し、それを直接呼び出していました。このため、this変数のスコープが間違っています。これは、#toggle-navをクリックするたびに、その関数が作成され、呼び出されてから破棄されることを意味します。クリックイベントの外に宣言すると、そのイベントは一度だけ作成され、クリックごとに再利用されます。 event.stopPropagation()も使用していましたが、使用している引数名はeでした。最後に、無名関数を.click関数に渡す必要はありません。あなたは名前で関数を渡すことができ、それは直接呼び出されます。

ここでは、これらの問題を解決するためにコードを少し整理しています。

jQuery(document).ready(function() { 
    jQuery('#toggle-nav').click(toggleNav); 

    function toggleNav(e) { 
     e.stopPropagation(); 
     jQuery(this).toggleClass('active'); 
     jQuery('.menu ul').toggleClass('active'); 
     jQuery('.hamburger ul').toggleClass('active'); 
     jQuery('.dimmer').toggleClass('active'); 
     jQuery('body').toggleClass('no-scrolling'); 

     e.preventDefault(); 
    } 
}); 

また、匿名関数を使用することもできます。

jQuery(document).ready(function() { 
    jQuery('#toggle-nav').click(function (e) { 
     jQuery(this).toggleClass('active'); 
     jQuery('.menu ul').toggleClass('active'); 
     jQuery('.hamburger ul').toggleClass('active'); 
     jQuery('.dimmer').toggleClass('active'); 
     jQuery('body').toggleClass('no-scrolling'); //Alternatively : jQuery(document.body) 

     return false; 
    }); 
}); 

eventeの使用については、this linkを参照してください。基本的に、一部のブラウザではグローバルコンテキストにeventプロパティが存在します。つまり、あなたのコードはそれらのブラウザで機能するかもしれませんが、他のブラウザでは機能しなくなります。 Clickイベントは自動的にイベントを最初の引数として指定の関数に渡します。そのため、そこに直接ブラウザ間でアクセスできます。

最後の注意として、jQueryイベントreturn false;を使用すると、e.stopPropagation();e.preventDefault();の両方が発生するので、falseを返す場合は、自分で呼び出す必要はありません。

jQuery source for reference

+0

これは絶対に素晴らしいことで、何が起こっているかを理解するのに大いに役立ちました。また、JQueryについて知っていることがほとんどなく、実際にC#とはどのように異なっているのか(これは私の仕事ですが、それでもまだ長い道のりがあります)を実感しました。あなたがやったことをやって、私がやろうとしていたことは正しいのでしょうか?つまり、clickイベントの中で関数を定義するのではなく、関数を別に作成して呼び出すほうがいいですか? – Damo

+0

私は助けてくれると嬉しかったです:)一般的には、匿名機能を使用するだけで苦労していないと思うのですが、私は答えを編集してその例を挙げました。 – Marie

+1

もう一度マリー、ありがとう。 – Damo

0

をあなたの元のコードでは、thisの値はを参照します#toggle-nav要素。改訂版では、thisはその親関数を参照しています。

+0

答えをありがとう、これは私が気付かなかった何かを指摘しました。 – Damo

0

あなたは、イベントリスナーのあなたの機能を移動する必要があります。

jQuery(document).ready(function() { 
    jQuery('#toggle-nav').click(function(e) { 
    e.stopPropagation(); 
    toggleNav(); 
    e.preventDefault(); 
    }); 
}); 

function toggleNav() { 
    jQuery('#toggle-nav').toggleClass('active'); 
    jQuery('.menu ul').toggleClass('active'); 
    jQuery('.hamburger ul').toggleClass('active'); 
    jQuery('.dimmer').toggleClass('active'); 
    jQuery('body').toggleClass('no-scrolling'); 
} 

また、thisが変更されているため、関数に正しいセレクタが追加されました。あなたが望むなら、あなたはイベントターゲットを渡すことができます(e.target多分、私は頭の上を思い出すことができません)。あなたの最後の質問に答えるために、あなたは問題の2つの行ではないと思うが、すべてのコードを見ることなく、私は確かに言うことができない。

+0

答えをありがとう。私はマリアの答えを受け入れるつもりですが、今までのすべての答えが私に何か新しいことを実感させてくれたので、感謝の言葉を伝えたいと思っていました。 – Damo

関連する問題