【问题标题】:How to change onClick handler dynamically?如何动态更改 onClick 处理程序?
【发布时间】:2010-09-19 22:18:05
【问题描述】:

我敢肯定有一百万个关于此的帖子,但令人惊讶的是,我找不到一些东西。

我有一个简单的脚本,我想在页面初始化时为 <A> 链接设置 onClick 处理程序。

当我运行此程序时,我立即收到一个“foo”警告框,我希望只有在单击链接时才会收到警告。

我做错了什么愚蠢的事情? (我试过 click= 和 onClick=)...

<script language="javascript">

    function init(){

        document.getElementById("foo").click = new function() { alert('foo'); };
    }

</script>

<body onload="init()">
    <a id="foo" href=#>Click to run foo</a>
</body>

编辑:我将接受的答案更改为 jQuery 答案。 'Már Örlygsson' 的答案在技术上是我原来问题的正确答案(click 应该是 onclicknew 应该被删除)但我强烈劝阻任何人使用 'document .getElementById(...) 直接在他们的代码中 - 并改用jQuery

【问题讨论】:

  • 为什么强烈劝阻?是不是很纯粹?
  • 我强烈反对任何人使用 jQuery 来完成像 document.getElementById(...)...这样简单的任务。
  • 确实奇怪的决定,我到这里是为了寻找 JS 解决方案,而不是 jQ...
  • @brasofilo 如果您已经在使用 jquery,那就太好了,因为 10 年前有更多的人使用。 jquery 语法看起来也更好看,所以当我已经在使用它时,我总是喜欢 jquery 语法。
  • 这不是重点。这个问题表明了一件事,你选择的答案是相反的。无论如何,大多数答案确实解决了您发布的问题,所以,我猜最后一切都很好:)

标签: javascript function


【解决方案1】:

试试:

document.getElementById("foo").onclick = function (){alert('foo');};

【讨论】:

  • 我没有意识到 new 会在页面初始化时调用该函数。很高兴知道。
  • @discorax 我也没有。事实上,直到现在!一年后
  • 我绝对不会再使用任何 getElementbyId 的东西了。在过去的一年里,我的 javascript 经验取得了长足的进步。绝对推荐 jQuery - 或其他一些这样的框架。 getElementById 现在已经过时了。请参阅下面@darryl 的答案
  • 从什么时候开始知道纯javascript已经过时了。
  • 我是一个完全的JS新手,但是我先学会了jQuery的选择方式,然后是getElementById。虽然我确实喜欢“查询”,但我认为它可能有点矫枉过正并且可读性差一些。当然,无论如何,大部分只是偏好:)
【解决方案2】:

使用.onclick(全部小写)。像这样:

document.getElementById("foo").onclick = function () {
  alert('foo'); // do your stuff
  return false; // <-- to suppress the default link behaviour
};

实际上,您可能会发现使用一些好的库(我推荐jQuery 有几个原因)让您启动并运行,并编写干净的 javascript 会更好。

跨浏览器(内)兼容性对于任何人来说都是一个正确的问题 - 更不用说刚刚开始的人了。

【讨论】:

  • 'return false;'恕我直言,这是一个重要的补充。
  • 是的,对于新手来说,return false 是完全不明显的。
【解决方案3】:

jQuery:

$('#foo').click(function() { alert('foo'); });

或者如果你不希望它跟随链接href:

$('#foo').click(function() { alert('foo'); return false; });

【讨论】:

  • 应该包裹在 $(function() { ... }; 中以便它运行(并且只有在 DOM 完成后才在 dom 中查找 'foo')
  • 这不是只唱链接,而是调用它。 $('#foo').onclick= 是这样做的好方法。
  • 您应该使用 preventDefault() 来停止链接的默认操作,而不是返回 false,因为 return false 也会停止传播(当在 jQuery 中使用时。) $('#foo').click (function(e) { e.preventDefault(); alert('foo'); }); More Info
  • 如果您不想让多个事件堆积起来,请务必先执行 $('#foo').unbind()。
  • event.preventDefault() 代替return false; 怎么样
【解决方案4】:

前几天我或多或少尝试了所有其他解决方案,但在我尝试这个之前,它们都没有为我工作:

var submitButton = document.getElementById('submitButton');
submitButton.setAttribute('onclick',  'alert("hello");');

据我所知,它运行良好。

【讨论】:

    【解决方案5】:

    如果要从当前函数传递变量,另一种方法是,例如:

    document.getElementById("space1").onclick = new Function("lrgWithInfo('"+myVar+"')");
    

    如果你不需要从这个函数传递信息,它只是:

    document.getElementById("space1").onclick = new Function("lrgWithInfo('13')");
    

    【讨论】:

    • 不知道为什么你被否决了。当您不想要闭包时,您的第一个示例是传递变量的好方法。
    • 这在 2021 年对我来说效果很好 - 我正在尝试使用一个函数 + 一个从 AJAX 传递的 var 来更改 onclick,但根本无法让它工作。可能不是最理想的解决方案但是对于我需要的技巧
    【解决方案6】:

    OMG...不仅仅是“jQuery Library”和“getElementById”的问题。

    当然,jQuery 帮助我们把跨浏览器的问题放在一边,但是如果你真的足够理解 JavaScript 的话,使用没有库的传统方式仍然可以很好地工作!!!

    @Már Örlygsson 和 @Darryl Hein 都为您提供了很好的替代方法(我想说,它们只是替代方法,而不是 anwsers),前者使用传统方式,后者使用 jQuery 方式。但是你真的知道你的问题的答案吗?你的代码有什么问题?

    首先,.click 是一种 jQuery 方式。如果您想使用传统方式,请改用 .onclick。或者我建议你只专注于学习使用 jQuery,以防混淆。 jQuery 是一个很好的工具,可以在不了解 DOM 的情况下使用。

    第二个问题,也是很关键的一个,new function(){} 是一个非常糟糕的语法,或者说它是一个错误的语法。

    不管你想用jQuery还是不用它,你都需要澄清它。

    有3种基本的函数声明方式:

    function name () {code}
    
    ... = function() {code} // known as anonymous function or function literal
    
    ... = new Function("code") // Function Object
    

    请注意,javascript 区分大小写,因此new function() 不是 javascript 的标准语法。浏览器可能会误解其含义。

    因此您的代码可以使用第二种方式进行修改

     = function(){alert();}
    

    或者使用第三种方式

     = new Function("alert();");
    

    细说一下,第二种方式和第三种方式几乎一样,第二种方式很常见,而第三种方式很少见。您的两个最佳答案都使用第二种方式。

    但是,由于“运行时”和“编译时”,第三种方式可以做第二种方式不能做的事情。我只是希望你知道new Function() 有时会很有用。有一天你在使用function(){} 时遇到问题,别忘了new Function()

    要了解更多信息,建议您阅读>,O'Reilly。

    【讨论】:

    • document.getElementById("foo").onclick = function() { alert('foo'); }; // 根据 Eric 的回答,只需要更改一行代码。这是整个事情:&lt;html&gt;&lt;head&gt;&lt;script&gt;function init(){ document.getElementById("foo").onclick = function() { alert('foo'); }; } &lt;/script&gt;&lt;/head&gt;&lt;body onload="init()"&gt;&lt;a id="foo" href=#&gt;Click to run foo&lt;/a&gt;&lt;/body&gt;&lt;/html&gt;
    【解决方案7】:

    我同意使用 jQuery 是最好的选择。你还应该避免使用 body 的 onload 函数,而使用 jQuery 的 ready 函数。至于事件监听器,它们应该是带有一个参数的函数:

    document.getElementById("foo").onclick = function (event){alert('foo');};
    

    或在 jQuery 中:

    $('#foo').click(function(event) { alert('foo'); }
    

    【讨论】:

      【解决方案8】:

      这是上面 jQuery 帖子的 YUI 对应项。

      <script>
        YAHOO.util.Event.onDOMReady(function() {   
          document.getElementById("foo").onclick =  function (){alert('foo');};
        });
      </script>
      

      【讨论】:

        【解决方案9】:

        我认为您想使用 jQuery 的 .bind.unBind 方法。在我的测试中,使用 .click 和 .onclick 更改 click 事件实际上调用了新分配的事件,从而导致了一个永无止境的循环。

        例如,如果您要在其中切换的事件是 hide() 和 unHide(),并且单击一个将单击事件切换到另一个,您将最终进入一个连续循环。更好的方法是这样做:

        $(element).unbind().bind( 'click' , function(){ alert('!') } ); 
        

        【讨论】:

          【解决方案10】:

          没有人解决正在发生的实际问题,以解释发出警报的原因。

          此代码:document.getElementById("foo").click = new function() { alert('foo'); };#foo 元素的 click 属性分配给一个空对象。这里的匿名函数是用来初始化对象的。我喜欢将这种类型的函数视为构造函数。您将警报放在那里,因此它会被调用,因为该函数会立即被调用。

          this question

          【讨论】:

            【解决方案11】:

            上面的 YUI 例子真的应该是:

            <script>
              YAHOO.util.Event.onDOMReady(function() {   
                 Dom.get("foo").onclick =  function (){alert('foo');};
              });
            </script>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-08-28
              • 1970-01-01
              • 2011-11-20
              • 1970-01-01
              • 1970-01-01
              • 2019-07-21
              • 1970-01-01
              相关资源
              最近更新 更多