1

私は一般的なOOPの概念にかなり慣れていないので、クライアント用にこのミニアプリケーションを構築しようとしています。モジュール番号などに基づいて構成可能なオプションがあるはずです。関連するものを保持するためにいくつかのコードを切り取りました。特に、これを可能な限りカスタマイズできるようにしようとしています。これにより、コーダーは、以下のオプション配列に追加することで、複数のライトボックススタイルのポップアップをサポートできるようになります。

これまではすべてうまくいきました。私の問題は、配列内の各オブジェクトを、構成を介して直接セレクターに文字列としてoptions.popupsフィードすることにより、jQueryでバインドしようとしていることです。selector$()

これclick()はオープナーへのバインドには問題なく機能しますが、selectorプロパティはバインドされません。毎回、次のエラーが発生します。TypeError: self.options.popups[i] is undefined.たとえば$(".helpPopup").show();、セレクターを直接挿入すると、正常に機能します。click()そのすぐ上の関数内の変数で定義すると、機能します。例えばvar s = ".helpPopup";

私がここで見逃している明らかなことはありますか?これは私を狂わせています。また、私のコードのデザインパターンはこれに直接基づいています:https ://github.com/shichuan/javascript-patterns/blob/master/jquery-plugin-patterns/prototypal-inheritance.html

ありがとう!

var MODULE = {
    init: function(options, elem) {
        // Stuff here

        this.bindPopups();
    },

    options: {
        title: "Module title",
        pages: 1,
        currentPage: 1,
        windowOpener: ".popupVar",
        popups: [
            { 
                name: "help", 
                selector: ".helpPopup", 
                opener: ".button.open", 
                closer: ".button.close",
                type: 3
            }
        ]
    },

    bindPopups: function() {
        var self = this;

        for(i = 0; i < this.options.popups.length; i++) {
            // Open the popup
            $(self.options.popups[i].opener).click(function(e) {
                e.preventDefault();
                $(self.options.popups[i].selector).show();
            });

            // Close the popup
            $(self.options.popups[i].closer).click(function(e) {
                e.preventDefault();
                $(self.options.popups[i].selector).hide();
            });
        }
    }
};

// If browser doesn't support Object.create
if(typeof Object.create !== "function") {
    Object.create = function(o) {
        function F() {
            F.prototype = o;
            return new F();
        }
    };
}

// Create plugin
$.plugin = function(name, object) {
    $.fn[name] = function(options) {
        return this.each(function() {
            if(!$.data(this, name)) {
                $.data(this, name, Object.create(object).init(options, this));
            }
        });
    };
};

$.plugin("module", MODULE);



/* PAGE CODE */
<script>
    $(function() {
        $("body").module({
            title: "Module 1",
            pages: 12,
            popups: [
                { 
                    name: "help", 
                    selector: ".helpPopup", 
                    opener: ".button.open", 
                    closer: ".button.close",
                    type: 3
                },
                {
                    name: "info",
                    selector: ".infoPopup",
                    opener: ".button.info",
                    closer: ".button.close",
                    type: 1
                }
            ]
        });
    });
</script>
4

1 に答える 1

0

何らかの理由で、iクリック機能内で増分しています。確認するにconsole.log(i);は、クリックイベント関数の直前に1つ、オープンクリック関数の内側に1つ配置します。

なぜこれが行われているのかわかりませんが(明らかなバグは見当たりません)、ループvar j = i;を開いた直後に配置して、インデックスセレクターとして使用するのが簡単なハックです。forj

編集:上記のハックは1回の反復でのみ機能します。ループが閉じられるまで評価されないため、ここiでは「増加しているように見えます」。forループが閉じられると、その時点でi増加します(クリックイベントの場合)。これは、たとえば関数i内にログインすることで確認できsetTimeoutます。

の適切な値を取得するにはi、クリックイベント関数を次のような無名関数でラップする必要があります。

$(self.options.popups[i].opener).click(
    (function (i) { 
        return function(e) {
            e.preventDefault();
            $(self.options.popups[i].selector).show();
        }
    })(i)
);

詳細については

于 2013-01-20T00:36:36.687 に答える