【问题标题】:onclick event not firing after onchange eventonchange 事件后未触发 onclick 事件
【发布时间】:2013-07-16 19:49:18
【问题描述】:

如果单击元素的过程导致页面上的其他地方触发 onchange 事件,有谁知道如何触发一个简单的 JavaScript onclick 事件?我创建了一个非常简单的页面来演示这个问题:

<html>
    <body>
        <input type="text" name="test" id="test1" onchange="return change(event);" />
        <a href="#" id="test2" onclick="return bang();">Bang</a>
        <a href="#" id="test3" onclick="return boom();">Boom</a>
        <script type="text/javascript">
            function change(event) {
                alert("Change");
                return true;
            }

            function bang() {
                alert("Bang!");
                return true;
            }

            function boom() {
                alert("Boom!");
                return true;
            }
        </script>
    </body>
</html>

如果您单击 bang 链接,您会收到 Bang!警报。 Boom 为您提供 Boom 警报。如果您在文本字段中输入文本并使用标签,您会收到更改警报。一切顺利。

但是,如果您在文本字段中输入文本,并且没有先使用 Tab 键或单击其他任何内容,则单击 Bang 或 Boom 您会收到更改警报,而没有其他任何内容。我希望看到更改警报,然后是 Bang 或 Boom。

这里发生了什么?我的更改事件返回 true。如何确保触发我的点击事件?

【问题讨论】:

  • 提示:在jsfiddle.net 上创建一个小提琴并在此处分享。这使人们更容易对其进行测试和提供帮助。
  • 您可能应该使用 addEventListener 而不是通过 html 分配它们作为提示。
  • 尝试使用console.log 而不是alert

标签: javascript


【解决方案1】:

问题是alert() 函数以某种方式抓取了事件链,测试一下:

<html>
<body>
    <input type="text" name="test" id="test1" onchange="return change(event);" />
    <a href="#" id="test2" onclick="return bang();">Bang</a> <a href="#" id="test3" onclick="return boom();">Boom</a>
    <script type="text/javascript">
        function change(event) {
          console.log("change");
            return true;
        }  

        function bang() {
            console.log("bang");
            return true;
        }

        function boom() {
            console.log("boom");
            return true;
        }
    </script>
</body>

如您所见,您将在控制台中获得预期的行为。

JSBin

【讨论】:

    【解决方案2】:

    好吧...看来是时间解释一下了。

    说明

    您会遇到此错误,因为一旦焦点从元素移开,就会触发 onchange 事件。在您的示例中,将焦点从input 元素移开的操作是mousedown 事件,该事件在您单击鼠标时触发。这意味着当您在链接上mousedown 时,它会触发onchange 函数并弹出警报。

    另一方面,onclick 事件是在 mouseup 事件上触发的(即,当您释放鼠标压力时 - 通过 click, hold/pause, releaseonlcick 事件上向自己证明这一点)。回到你的情况......在mouseup(即onclick)发生之前,焦点将转移到alert 触发的onchange 函数。

    修复

    有几个选项可以解决此问题。从使用onclick="...."onmousedown="...." 的最简单更改。

    或者,您可以使用 setTimeout 之类的:

    function change() {
        setTimeout(function (){
            alert("Change event")
        }, 100)
    }
    

    我建议首选onmousedown 方法。如果您在链接上单击并按住超过规定的超时时间,setTimeout 方法将失败。

    【讨论】:

      【解决方案3】:

      我没有尝试复制您的问题,而是在jsFiddle 中创建了解决方案。

      我分离了你的 HTML 和你的 JavaScript。

      HTML

      <input type="text" name="test1" id="test1" />
      <a href="#" id="test2">Bang</a> 
      <a href="#" id="test3">Boom</a>
      

      JavaScript

      var test1 = document.getElementById("test1");
      var test2 = document.getElementById("test2");
      var test3 = document.getElementById("test3");
      
      test1.onchange = function (event) {
          alert("Change");
      };
      
      test2.onclick = function () {
          alert("Bang!");
      };
      
      test3.onclick = function () {
          alert("Boom!");
      };
      

      在文本框中进行更改并单击它的外侧后将触发onchange 事件,并且onclick 事件仍将触发。如果您希望每次击键都会触发更改警报,请将onchange 更改为onkeyup

      【讨论】:

      • 您已经重现了问题...此代码与提问者发布的原始代码具有相同的缺陷。
      • @Steven 然后我真的看不出缺陷是什么,除非它是特定于浏览器的。因为使用 Chrome,我没有任何问题。
      • 对不起,我应该解释一下的。他遇到的问题是,当您在输入字段中输入内容然后立即单击其中一个链接(即在跳出input 或单击页面上的任何其他位置之前) onclick 事件不会触发(当inputonchange 事件中有alert(...) 时)。您的代码依赖于在单击文本链接之前已经从 input 更改焦点。 (您的浏览器中可能不会发生这种行为......我已经用 FF 和 Chromium 进行了测试。修复将更改为 onmousedown(见上文)
      猜你喜欢
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多