0

我从这个问题开始:Multiple Javascript gadgets per page。在阅读了如何构建 jQuery 插件之后,我通过将我的 JS 对象包装在

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

并添加一个

function createMyGadget() { return new myObject }

在我的对象中。我现在可以通过执行以下操作在一个页面上成功显示两个小工具:

<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 ( gadgetUID) 的新 div,将一堆 HTML、按钮、imgs 等写入该 div,然后将该 div 附加到#fooand #bar。效果很好。

在我的 HTML 中,我有一个“下一步”按钮,它需要调用goNext()JavaScript 对象中定义的函数。如何在该对象中引用该函数?我试过了

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

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

以及我能想到的所有其他排列。Firebug 总是以错误消息“...不是函数”作为响应。

附录:这是我对 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 执行此操作,但将其更改为按钮,以便我可以复制/粘贴您的代码。

I'm starting to think I have something else wrong and this is just a weird by-product.

ADDENDUM: I figured out the problem: I'm an idiot (but any of my xGFs could have told you that).

I was calling the pageData() on the element in question. There is no pageData() function on the element; it's on the 'this' object. Onc I pointed to the correct (and only) pageData() object (which is attached to 'this'), it worked as advertised.

Now to go do some code cleanup.

4

2 回答 2

1

if you're writing the onclick handler as part of the HTML that gets appended to the DOM, try something like this:

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

Or, you could use jQuery to bind the handler inside plugin code. Without seeing a code sample, it's hard to say exactly what you need. But this is the general idea:

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

EDIT: It sounds like this is a scoping problem. Calling pageData() in correct scope should fix your problem. Maybe something like this would work:

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!
}

Note that I changed the jQuery selector back to match your original code (the image tags).

If you're planning on having multiple instances of this HTML on a page, one thing you might want to consider is using classes instead of IDs for the generated DOM elements. Giving the same ID to more than one DOM element is generally a bad thing and can cause you some headaches and bugs further down the road.

Also, you might want to look into DOM node creation instead using innerHTML to generate the controls. It would be easier to keep references to the elements and hook event handlers onto them.

于 2009-12-10T22:07:46.133 回答
0

Perhaps this is what you're thinking of...

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

This creates a reference to an anonymous function that finds your JQuery object(s) and runs the function you want to run.

于 2009-12-10T21:50:05.090 回答