开发者

What is the OO approach to accessing jQuery plugin methods from my plugin HTML?

I started with this question: Multiple Javascript gadgets per page . After reading up on how to build a jQuery plugin I've modified my OO JavaScript object into a jQuery plugin by wrapping my JS object in

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

and adding a

function createMyGadget() { return new myObject }

in my object. I can now successfully display two gadgets on one page by doing the following:

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

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

As part of the createMyGadget() function, I create a new div with a unique ID (gadgetUID), write a bunch of HTML, buttons, imgs, etc. to that div, then append that div to #foo and #bar. That works well.

In my HTML, I have a "Next" button which needs to call the goNext() function which is defined in the JavaScript Object. How do I reference that function in that object? I've tried

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

and

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

and every other permutation I could think of. Firebug always responds with an error message "...not a function".

ADDENDUM: Here's my response to johnnyheadphones :

I've been trying to do the same thing from inside of jQuery with the same results, e.g. '...is not a function'. Here's the actual function call:

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>\
    &l开发者_StackOverflow社区t;div id=\"debugInfo\"></div>\
            <script type=\"text/javascript\"> \
            </script>\
    ";

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

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

When I reload and click the next button, Firebug says '$('#'+this.gadgetId).pageData(1) is not a function'.

BTW, I initially wanted to do this with the goNextIcon but changed it to a button so I could copy/paste your code.

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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜