【问题标题】:How to call a JQuery function defined in $(window).load from an HREF如何从 HREF 调用 $(window).load 中定义的 JQuery 函数
【发布时间】:2011-09-08 15:00:03
【问题描述】:

我喜欢将我的所有 JQuery 函数和事件接收器的范围限定为 $(window).load,如下所示:

$(window).load(function ()
{
   function Foo(id)
   {
      alert(String.format("Do Foo for: {0}", id));
   }
});

通常,我在此范围内完成所有工作,但我有一个案例,我想从由独立 JQuery 小部件构建的 HREF 调用 Foo(27)。 HREF 如下所示:

<a href="javascript:Foo(27)">Click me!</a>

但是,当我单击链接时,找不到 Foo() 函数。我怎样才能做到这一点?

[编辑]

所以,我刚刚接受了下面的答案,并想分享我的最终实现。 Foo() 已替换为我正在使用的实际方法的名称。是的,我知道 String.format() 本身并不存在;它是我自己的基础库的一部分。考虑到这一点,这就是我所拥有的。这是来自我定义所有全局名称空间的文件。此定义存在于 jQuery 范围之外。

// This is defined in the global namespace
if (typeof (window.App) === "undefined")
{
   window.App = {};
}

这是构建 HREF 的 jQuery 小部件中的一行。标题用于预测,HREF 导航到该预测的详细信息页面:

r = String.format('<a href="javascript:App.NavDetails({1});" class="link3">{0}</a>',
   Predikt.General.EncodeHtml(options.rowData.Title), 
   options.rowData.PredictionId);

这是我的 $(window).load()-scoped jQuery 文件中 NavDetails 函数的实际实现:

$(window).load(function ()
{
   App.NavDetails = function (id)
   {
      // Do something interesting with the ID here...
      alert(String.format("The ID is: {0}", id));
   };
});

【问题讨论】:

  • javascript 中没有String.format。还请详细说明您想在加载时传递给Foo 的内容?

标签: javascript jquery scope href


【解决方案1】:

你可以这样做

$(window).load(function (){
    window.Foo =  function(n){
      alert(n);
   }
});

http://jsfiddle.net/JQn8H/

或者这个

var Foo;

$(window).load(function (){
    Foo =  function (n){
      alert(n);
   }
});

http://jsfiddle.net/JQn8H/2/

IMO,更好的方法是为您的应用设置命名空间,这样您就不会污染全局命名空间

window.App = {};

$(window).load(function (){
   App.Foo =  function (n){
      alert(n);
   }
});

然后,在您的 html 中,您可以调用它:

<a href="javascript:App.Foo(27)">Click me!</a>

http://jsfiddle.net/JQn8H/3/

但是,您可能需要考虑从脚本而不是标记中调用它。

【讨论】:

  • 但是如何从 HREF 中调用它?
  • 你正在内联,检查我发布的小提琴&lt;a href="javascript:Foo(27)"&gt;Click me!&lt;/a&gt;
  • 从技术上讲,如果Foo 是全球性的,则根本不需要var Foo。我更喜欢你的第一种方法,因为它更明确。
  • 不错!我想我们在这里有一个赢家!我也更喜欢第一个版本。之前没有使用过jsfiddle.net,所以我最初没有点击你的链接。认为这是一些文档的链接。在接受这个答案之前,我会稍等片刻,但到目前为止,这正是我想要的。它基本上颠覆了我原来的问题。不是装饰来自 HREF 的调用,而是告诉 $(window).load() 中的函数查找从全局范围调用的函数。非常聪明。
  • 我喜欢你用 window.App 编辑的版本。当我编写自己的 jQuery 小部件和控件时,我总是将它们限定在它们自己的命名空间中,所以我想我不妨对原本存在于全局命名空间中的 Javascript 做同样的事情。再次感谢所有这些很棒的建议以及 jsfiddle 的链接(基于我迄今为止所看到的一点点,注定会成为我最喜欢的编程相关网站之一)。
【解决方案2】:

您必须在在该范围内工作和拥有这样可访问的功能之间做出选择。唯一的其他选择是强制重新加载或将其绑定到锚点的单击处理程序。

此外,您可能已更改原型,但除非您更改,否则String.format 不起作用。你可能只想做"Do Foo for: " + id

function Foo(id) {
  alert("Do Foo for: " + id);
}
$(window).load( ... );

<a class="someClass" data-id="23">Click me!</a>

...

$(window).load(function() {
  $("a.someClass").click(function() {
    alert("Do Foo for: " + $(this).data("id"));
  });
});

【讨论】:

  • 是的,除非有人单独提出更好的解决方案,否则这就是我已经在做的事情。一般来说,当存在替代品时,我会尽量避免使用 expando 属性。在这种情况下,我希望只是将 ID 作为参数传递给 Foo()。但由于我不能这样做,我将把 ID 添加为 expando,将共享 CSS 类添加到锚点,接收该 CSS 类上的点击事件,然后提取 expando ID 值。
  • 顺便说一句:重新 String.format -- 这已经是我拥有的另一个库的一部分,并且非常依赖于我不能再编写执行古老字符串连接的代码! :-) 带有可替换参数的 String.format() 是这个库中我最喜欢的功能之一。
  • 我对数据属性有同样的不情愿态度(试图找到一个留在 JS 内部的解决方案),尽管它们已经派上用场了。当我将 Chrome 扩展程序国际化时尤其如此(将标签中的所有文本替换为 data-i18n="someString")。您可以使用单独的静态 HTML 页面,但这很痛苦。至于String.format,我喜欢它在许多原生语言中的表现,我只是想确保你不是对 JS 本身抱有同样期望的 Java/C# 人。 ;)
  • 我是一名 C# 人员,大约 18 个月前我开始使用 jQuery 时,我首先寻找的是 String.format() 的高性能版本。事实证明那里有很多和很多实现;有些针对较短的字符串进行了优化,有些针对较长的字符串或几十个参数进行了优化。我终于找到了一个万事通但一无所获的东西。
【解决方案3】:

要么将 Foo 函数移到 $(window).load() 函数之外,要么将 Foo 绑定到加载函数内的 &lt;a&gt; 元素。您无法从外部进入您的 $(window).load() 回调。


从您的 cmets 看来,您需要 Foo 留在您的 $(window).load() 匿名函数中,因为它需要访问该范围内的其他内容。您可以通过在匿名函数之外移动对Foo 的引用来解决此问题。 jm-'s 方法的这种变体:

$(window).load(function() {
    //...
    function Foo() {
        //...
    }
    //...
    window.Foo = Foo;
});

这会在window 对象中留下对Foo 的引用,并且由于window 是默认范围,您应该能够在&lt;a&gt; 元素中访问它。

【讨论】:

  • 该死。我希望我可以以某种方式装饰从 HREF 对 Foo 的调用(例如 Click me! 或其他东西)以使 Foo() 可见。我无法将 Foo() 移动到全局空间,因为在 $(window).load 中有我需要访问的变量和支持函数。所以我想当我构建锚标记时,我只需要将 ID 存储在 expando 属性中,然后使用传统的 jQuery 语法接收点击事件。然后 this 可以调用 Foo() 并传入 $(this),然后我可以从 Foo() 查看 expando 以获取 ID。
  • @Armchair:您可以将Foo 保留在原处(因此它可以访问当前范围内的所有内容),然后为其设置一个在外部可见的别名,有点像jm-的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
  • 2016-10-11
  • 1970-01-01
相关资源
最近更新 更多