0

現在、コードをオブジェクト内に保持するために、クリックイベントの内容をメソッドに変換したいのですが、これがどのように行われるかについてはあまりわかりません。現在のコードは次のようになります。

現在のJS

init: function(){

            var _this = this,
                slides_li = _this.els.slides.children(),
                large = 260,
                small = 60;

            // Hover
            slides_li.on('mouseover', function(){
                $(this).stop(true, true).animate({ opacity: 1 }, 300);
            }).on('mouseout', function(){
                $(this).stop(true, true).animate({ opacity: .8 }, 300)
            });

            // Click handlers
            slides_li.on('click', function(){

//このコードを独自のメソッドtoggle_slides()に移動しますか??

                $('.active', _this.els.slides).not(this).animate({
                    width: small
                }, 300).removeClass('active');
                // animate the clicked one

                if ( !$(this).hasClass('active') ){
                    $(this).animate({
                        width: large
                    }, 300).addClass('active');
                }                
            });                 
        }

しかし、コードを次のようにしたいと思いますが、いくつかの重要な点が欠落していることはわかっています。さらに、これは明らかにクリックされたイベントを意味するものではありません。

JS

init: function(){

            var _this = this,
                slides_li = _this.els.slides.children(),
                large = 260,
                small = 60;

            // Hover
            slides_li.on('mouseover', function(){
                $(this).stop(true, true).animate({ opacity: 1 }, 300);
            }).on('mouseout', function(){
                $(this).stop(true, true).animate({ opacity: .8 }, 300)
            });

            // Click handlers
            slides_li.on('click', function(){
                toggle_slides(); //pass in this?
            });                 
        },
        toggle_slides: function(){ // add argument for this?
               $('.active', _this.els.slides).not(this).animate({
                    width: small
                }, 300).removeClass('active');
                // animate the clicked one

                if ( !$(this).hasClass('active') ){
                    $(this).animate({
                        width: large
                    }, 300).addClass('active');
                }                
        }

誰かがこれを機能させる方法についてアドバイスを提供できますか?

4

1 に答える 1

2

問題は、コンテキストに依存する「this」の値です。

まず、元のコードがどのように機能したかについてのメモ:

init()が最初に呼び出されたときthis、親オブジェクト(gep)を参照します。ただし、クリックイベントハンドラー内では、thisクリックされた要素を参照します。クリックハンドラー内で引き続き親にアクセスできるように、「thisの親値」をにキャプチャし_thisて、後で使用できるようにします。これで、すべてが正常に機能します。

ただし、ハンドラー内のコードを別のメソッドに移動すると、かなりの数の変更が行われます。

  • まず、small、large、およびその他の変数はローカルスコープに存在しないため、再定義するか、パラメーターとしてインポートする必要があります。

  • this現在実行中のメソッドはイベントハンドラーではなく、親要素のメソッドであるため、今度は親要素を再度参照します。したがって_this、古いコードでの参照thisは、新しいコードで使用できます。

  • 最後に、古いコードでは、イベントハンドラーで、thisクリックされた要素を参照していました。しかし(上記を参照)、新しいメソッドでは、これは別の意味を持ちます。「親」オブジェクトです。したがって、クリックされた要素をキャプチャするためのパラメータが必要です。これをパラメータとして渡しました。古いコードでのel参照はそれに応じて変更されます。this

したがって、注意すべき本当のことは、このコードがどのオブジェクトに属しているかということです。あるオブジェクトに属するコードを別のオブジェクトに移動する場合-たとえば。あるオブジェクトのイベントハンドラーから別のオブジェクトのメソッドへ-必要に応じて、thisまたはthis-like変数を作り直す/名前を変更する必要があります。

更新されたコードの注釈付きコピーが続きます。jsfiddleとしても利用できます。

...
        // Click handlers
        slides_li.on('click', function(){
            // pass 'this' - the clicked element - as the el param; also small and large.
            gep.toggle_slides(this, small, large);
        });                 
    },

    toggle_slides: function(el, small, large){
           // '_this' in old code in handler replaced with 'this';
           // 'this' in handler code replaced with 'el' here
           $('.active', this.els.slides).not(el).animate({
                width: small
            }, 300).removeClass('active');
            // animate the clicked one

            // 'this' in handler code replaced with 'el'here
            if ( !$(el).hasClass('active') ){
                $(el).animate({
                    width: large
                }, 300).addClass('active');
            }                
    }
于 2012-06-13T09:55:31.940 に答える