0

私はこの質問から始めました: Multiple Javascript gadgets per page . jQuery プラグインの作成方法を読んだ後、JS オブジェクトをラップすることで、OO JavaScript オブジェクトを jQuery プラグインに変更しました。

(function {} { /*my object code*/ }(jQuery))

を追加する

function createMyGadget() { return new myObject }

私のオブジェクトで。次のようにして、1 つのページに 2 つのガジェットを正常に表示できるようになりました。

<div id="foo"></div>
<div id="bar"></div>

<script language="JavaScript">
    $("#foo").createMyGadget({ title: "My First Gadget"});
    $("#bar").createMyGadget({ title: "My Second Gadget"});
</script>

関数の一部としてcreateMyGadget()、一意の ID ( ) を持つ新しい div を作成し、gadgetUIDその div に多数の HTML、ボタン、img などを書き込み、その div を#fooandに追加します#bar。それはうまくいきます。

私の HTML にはgoNext()、JavaScript オブジェクトで定義された関数を呼び出す必要がある「次へ」ボタンがあります。そのオブジェクトでその関数を参照するにはどうすればよいですか? 私はもう試した

onClick='$("#foo").goNext()'

onClick='$("#gadgetUID").goNext()'

そして、私が考えることができる他のすべての順列。Firebug は常に「...not a function」というエラー メッセージで応答します。

補遺: johnnyheadphonesに対する私の応答は次のとおりです。

jQuery の内部から同じことを試みましたが、同じ結果が得られました。たとえば、「... 関数ではありません」。実際の関数呼び出しは次のとおりです。

displayGadget : function() {

    var myString = "\
    <div id=\""+this.gadgetId+"\" >\
        <div id=\"gadget_header\">\
            <h1 id=\"title\">"+this.options.title+"</h1>\
        </div>\
        <div id='loading' style=''><img src='images/loading2.gif' /></div> \
        <div id=\"gadget_body\"></div>\
        <div id=\"gadget_footer\">\
            <div id=\"searchAsset\">\
            </div>\
            <div id=\"pageControls\">\
                <img id=\"goPreviousIcon\" src=\"images/go-previous.png\">\
                <img id=\"goNextIcon\"  src=\"images/go-next.png\">\
                <input type=\"button\" value=\"Next\" />\
            </div>\
        </div> \
    \
    </div>\
    <div id=\"debugInfo\"></div>\
            <script type=\"text/javascript\"> \
            </script>\
    ";

    $("#"+this.gadgetContainerID).html(myString);

    $('input[value="Next"]','#'+this.gadgetContainerID).click(function() {
        $('#'+this.gadgetId).pageData(1);
    });
}

リロードして次のボタンをクリックすると、Firebug に「$('#'+this.gadgetId).pageData(1) は関数ではありません」と表示されます。

ところで、最初は goNextIcon でこれをやりたかったのですが、コードをコピーして貼り付けることができるようにボタンに変更しました。

他に何か問題があると思い始めていますが、これは単なる奇妙な副産物です。

補遺:私は問題を理解しました.

問題の要素で pageData() を呼び出していました。要素には pageData() 関数はありません。それは「this」オブジェクトにあります。正しい (そして唯一の) pageData() オブジェクト (「this」に関連付けられている) を指定すると、宣伝どおりに機能しました。

次に、コードのクリーンアップを行います。

4

2 に答える 2

1

DOM に追加される HTML の一部として onclick ハンドラを記述している場合は、次のようにしてみてください。

<input type="button" value="Next" onclick="function() { $('#gadgetUID').goNext(); }" />

または、jQuery を使用してプラグイン コード内でハンドラーをバインドすることもできます。コード サンプルを見ないと、必要なものを正確に言うのは困難です。しかし、これは一般的な考え方です:

$('input[value="Next"]','#foo').click(function() {
    $('#gadgetUID').goNext();
});

編集:これはスコープの問題のようです。正しいスコープで pageData() を呼び出すと、問題が解決するはずです。たぶん、このようなものがうまくいくでしょう:

displayGadget : function() {
    // encapsulate this in a closure, so pageData() is called on the instance
    // of the object, not the DOM element selected by jQuery
    var that = this;

    [... string stuff here. you should replace 'this' with 'that' here as well ...]

    $("#"+that.gadgetContainerID).html(myString);

    $('#goNextIcon','#'+that.gadgetContainerID).click(function() {
        that.pageData(1);
    });
},

// the above code assumes that pageData() is part of the same
// object instance as displayGadget. if not, then you'll have to
// tweak your code to point call pageData in the correct scope
pageData: function( page ) {
    // do stuff here!
}

元のコード (イメージ タグ) に一致するように jQuery セレクターを元に戻したことに注意してください。

ページ上にこの HTML の複数のインスタンスを配置することを計画している場合、考慮すべきことの 1 つは、生成された DOM 要素に ID の代わりにクラスを使用することです。複数の DOM 要素に同じ ID を付与することは、一般的に悪いことであり、後で頭を悩ませたりバグを引き起こしたりする可能性があります。

また、innerHTML を使用してコントロールを生成する代わりに、DOM ノードの作成を検討することもできます。要素への参照を保持し、イベント ハンドラーを要素にフックする方が簡単です。

于 2009-12-10T22:07:46.133 に答える
0

たぶん、これはあなたが考えていることです...

onClick = function() {
    $("#gadgetUID").goNext();
}

これにより、JQuery オブジェクトを見つけて実行したい関数を実行する無名関数への参照が作成されます。

于 2009-12-10T21:50:05.090 に答える