【问题标题】:Onsubmit event silently killed by onchangeOnsubmit 事件被 onchange 静默杀死
【发布时间】:2011-11-04 17:16:48
【问题描述】:

Onsubmit 事件可以静默地杀死 onchange 事件,如果同时调用的话。我假设 js 引擎中的竞争条件。在 chrome、FF3、FF6 和 IE9 中测试。

要重现,您需要更改输入内容并单击提交按钮。不要在输入更改和提交按钮点击之间进行任何额外的点击。

<div id="somediv">
    <div>one</div>
    <div>two</div>
</div>
<form method="POST" id="someform">
    <input type="text" name="input1" id="someinput" value="change me" />         
    <input type="submit" />
</form>
<script type="text/javascript">
    document.getElementById('someinput').onchange = function() {
        //some delay - DOM operations, AJAX or alert:
        document.getElementById('somediv').getElementsByTagName('div')[1].style.display = 'none';
        //or alert('123');
    }
    document.getElementById('someform').onsubmit = function() {
        alert('This event is not called');
    }
</script>

预期行为:onchange 事件,而不是 onsubmit。

如果我们使用按钮而不是一个接一个地提交和调用事件 - 一切都会按预期工作。

如果 onchange 事件中没有操作(无延迟) - 按预期工作。

如果 onchange 会改变 div 的颜色(不显示) - 有时 (3/10) 会按预期工作,哈哈。

js-guru,请解释一下,到底发生了什么?

【问题讨论】:

  • 这不是竞争条件。除了网络工作者之外,JavaScript 在每个浏览器的单个线程中执行。
  • 好吧,就这样吧。但它比什么呢?
  • 我正在尝试在 Ubuntu 上的 Chrome 中重现它 - 不走运(尝试了几十次)。每次两个回调都被触发。可能是特定于操作系统的东西吗?
  • 一分钟前在 Ubuntu 10 上的 Chrome 15.0.874.120 中尝试过:未提交表单。你确定,你能正确地复制它吗?您应该在更改“输入”后立即单击“提交”。
  • 创建了一个 jsFiddle 来查看这种奇怪的行为:jsfiddle.net/amwebexpert/Lmdp6bp7

标签: javascript events browser dom-events


【解决方案1】:

onsubmitonclick 类似,需要连续发生 onmousedownonmouseup 事件。如果您的代码在onmouseown 事件之后显示一个对话框(例如警报)或替换按钮,则不会触发后续的onmouseup 并因此取消该事件。用 somediv 交换文本框和按钮应该会有所帮助。

【讨论】:

  • 感谢您的回复,但我的代码中没有显示警报替换提交按钮。我只是隐藏了一个 div(该 div 内没有表单或按钮)。
  • 至于警报,这是一个例子。另一方面,隐藏“somediv”会向上移动按钮。您是否尝试过交换他们的位置。
  • 使用 onmousedown 和 onclick 检出代码 - 你是对的。谢谢,这是一个非常神秘的问题!
【解决方案2】:

请注意,出现对话框打开时JS引擎不运行提交的问题:Javascript onchange event preventing onsubmit event in HTML form?

事实证明,它只存在一个 alert() - 或一个 confirm() - 在导致表单的 onsubmit 的输入的 onchange 事件期间 事件不触发。 JS 线程似乎被 警报()。解决方法是不包括任何警报()或确认() 输入的 onchange 调用。

他们可能通过在 onchange 调用中禁止 alert() 或 confirm() 命令来解决该错误,以允许表单按预期提交。

【讨论】:

  • 我已经阅读了那篇文章。您可以将我的代码中的“警报”替换为其他一些“延迟”。例如。一些 DOM 操作。
  • 从我的代码中删除了“警报”。现在只有 DOM 操作。事件仍然消失。
  • 在 Chrome/OSX 上,如果我修改 HTML 以阻止提交按钮移动位置(移动表单下方的 div),代码每次都有效。但是,在警报中回复评论会返回您最初的投诉 - 只有 onchange 会触发。
  • 再想一想,这是一个合理的结果。如果有关于 onchange 的警报,作为用户,我可能不希望提交表单,因为警报可能告诉我一个问题。用户可以关闭警报并立即再次单击提交按钮。
  • 在上面的代码中,onchange 事件正在删除其中一个 div,在 Chrome/OSX 上它会导致提交按钮更改位置;它向上移动页面。当这种情况发生时,它似乎放弃了提交。但是,当我更改 html 以将 div 数据放置在表单下方时,onchange 不再移动提交按钮并且它表现得更好——它按预期工作并每次都触发这两个事件。在 alert('123') 中评论后,它又回到只运行 onchange。
猜你喜欢
  • 1970-01-01
  • 2018-02-27
  • 2015-12-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多