【问题标题】:Invoking the HREF attribute of a link with javascript using javascript!使用 javascript 调用带有 javascript 的链接的 HREF 属性!
【发布时间】:2010-09-11 05:56:26
【问题描述】:

我以前从未见过这种情况,但如果 HREF 包含 javascript:;//code......;

在下面的示例中,单击两个链接。即使他们在 HREF 中有不同的 javascript,他们也会做同样的事情。

例如:

     <script type="text/javascript">
            function clickme()
            {
                var link = document.getElementById("clickme");
                eval(link.href);
            }
    </script>
    <a id="clickme" href="javascript:alert('hello');">I will alert hello</a>
    <br />
    <a href="javascript:clickme()">click me</a>

我在 IE8、Firefox 3.6.8、Safari 5.0.1 和 Chrome 6.0.472.55 上对此进行了测试。这是标准化的,所以我不必担心将来会弃用此功能吗?

【问题讨论】:

  • 答案是:你不应该这样做。

标签: javascript click href invoke


【解决方案1】:

您不必担心它将来会被弃用。 现在是个坏主意。

真正发生的事情是:有一个使用javascript: 协议的链接,该协议受到浏览器的尊重。也就是说javascript:后面的都是JavaScript,应该由JS解释器来执行。

当您检索链接的 href 时,您会收到一个字符串,例如“javascript:clickme()”。您可以在字符串上使用 eval 来执行 JavaScript。现在,您会认为这会失败(因为前面的 javascript: 协议),但事实并非如此,因为 JavaScript 有 labels 并且当您对待它时它看起来像一个标签作为 JavaScript 代码。

所以它有效,但这是一个坏主意。在最新版本的 JavaScript,ECMAScript 第 5 版的新“严格”模式中,它也被禁止(因为 eval)。

一般来说,当我们认为需要使用eval 时,这表明我们的代码存在问题,需要进行一些重构。该规则的例外是我们大多数人永远不会遇到的非常边缘的边缘情况。在这种情况下,与其让href 属性包含我们想要执行的代码,不如使用我们想要执行的代码。例如,您的示例有一个 clickMe 函数作为唯一使用的东西。我们应该直接调用该函数,而不是evaling。

【讨论】:

  • 标签的解释很好。
  • Eval 在 .NET 中被大量使用,尤其是 ajax 工具包。此外,在我的情况下,Eval 非常必要,因为我正在尝试执行链接按钮控件的单击事件。我觉得不需要剥离代码,将其绑定到点击事件并调用它。
  • @ncaatrackstar:.Net 工具包使用eval 的事实并不是说这样做是件好事。 ;-) 在您的情况下不是必要的,这是您正在做出的选择。这很好,这是您的选择,但完全没有必要。
  • 你是对的,T.J(关于我有一个选择)。我可以使用 window.location = link.href,来完成我的任务。谢谢。您提到 eval 在 ECMAScript 第 5 版中将被“禁止”,这是在哪里提到的。如果这是真的,数以百万计的网站注定要失败。
  • @Robert:只有在严格模式下,这是你(程序员)必须明确启用的(但如果你这样做的话会做一些有用的事情)。更多信息:ejohn.org/blog/ecmascript-5-strict-mode-json-and-more
【解决方案2】:

它不会被弃用,但我看不到它的用途。

如果您确实想简化此操作,请执行以下操作:

 <script type="text/javascript">
            function clickme()
            {
                 clicked();
            }
            function clicked()
            {
                alert("hello");
            }

    </script>
<a id="clickme" href="javascript:clicked();">I will alert hello</a>
<br />
<a href="javascript:clickme()">click me</a>

或者更好:

  <a href="#" onclick="clicked();">Click Me</a>

甚至更好:

<span onclick="clicked();" class="MakeMeLookLIkeLInk">Click Me</a>

锚点控件主要用于导航,并作为一种很好的做法来保持这种状态。如果您有需要执行的功能,请使用带有 onclick 的 span/div。您也可以使用按钮。

【讨论】:

    【解决方案3】:

    我认为你的问题是是否行

    eval(link.href);
    

    有效。

    答案是肯定的。没有理由不能评估存储在某个属性中的代码,就像评估输入框的内容一样。

    也就是说,这看起来是一种非常糟糕的编码方式。如果你不小心,你可能会陷入一个循环。此外,这样的代码将很难维护。

    【讨论】:

    • 谢谢保罗。我没想到 javascript:// 和一些代码;被认为是可以评估的代码。
    • 这不是... // 不能正常工作。 T.J. 的回答很好解释。