【问题标题】:What is the OO approach to accessing jQuery plugin methods from my plugin HTML?从我的插件 HTML 访问 jQuery 插件方法的 OO 方法是什么?
【发布时间】:2009-12-10 21:17:08
【问题描述】:

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

中,将我的 OO JavaScript 对象修改为 jQuery 插件
(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 附加到@987654327 @ 和 #bar。效果很好。

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

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

我开始认为我还有其他问题,这只是一个奇怪的副产品。

附录:我发现了问题:我是个白痴(但我的任何 xGF 都可以告诉你)。

我在有问题的元素上调用 pageData()。元素上没有 pageData() 函数;它在“this”对象上。一旦我指向正确的(也是唯一的)pageData() 对象(附加到“this”),它就可以像宣传的那样工作。

现在开始做一些代码清理。

【问题讨论】:

  • 将最后一条错误消息读取为“...pageData(1) 不是函数”。你真的打算调用“pageData”方法吗?它只是没有定义。

标签: javascript jquery jquery-plugins jquery-events


【解决方案1】:

如果您将 onclick 处理程序编写为附加到 DOM 的 HTML 的一部分,请尝试以下操作:

<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 的多个实例,您可能需要考虑的一件事是为生成的 DOM 元素使用类而不是 ID。为多个 DOM 元素提供相同的 ID 通常是一件坏事,并且可能会在以后给您带来一些麻烦和错误。

此外,您可能希望查看 DOM 节点创建,而不是使用 innerHTML 来生成控件。保留对元素的引用并将事件处理程序挂钩到它们会更容易。

【讨论】:

  • 在我的帖子中查看我对您的回复。
  • pageData() 是在哪里定义的?它是具有 displayGadget() 的同一对象的方法吗?如果是这样,请查看我的帖子的编辑。
  • 是的,pageSata() 与 displayGadget() 定义在同一个对象中(通过 .prototype)。我同意这是一个范围界定问题,但所有方法都是公开的,所以 WTF?我在你的解决方案中没有看到任何我还没有尝试过的东西,但我会在早上再试一次。感谢您提醒从 ids 切换到 classes。在我开始与鳄鱼搏斗之前就打算这样做。
  • 所以您尝试将“this”设置为一个变量,以便在闭包中捕获它?我很确定这将保持范围。我在您的代码中看不到任何创建 $('#'+gadgetId) 作为对象实例的内容,所以我猜测 getData() 方法是另一个对象的公共属性。您是否尝试在点击处理程序中的 Firebug 中设置断点并观看 $('#'+gadgetId)?它可能会表明 jQuery 对象没有 getData();
【解决方案2】:

也许这就是你的想法……

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

这会创建一个匿名函数的引用,该函数会找到您的 JQuery 对象并运行您要运行的函数。

【讨论】:

  • 那个,以及我尝试过的每一个排列,都会给我一个语法错误
猜你喜欢
  • 2012-04-25
  • 2013-07-11
  • 1970-01-01
  • 2013-03-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
相关资源
最近更新 更多