在事件冒泡阶段删除祖先
Removing an ancestor during the event bubbling phase
在下面的代码中(JSFiddle在这里(:
<form>
<button>ok</button>
</form>
$(function(){
$('form').submit(false) ;
$('button').click(function(){ $('form').remove() }) ;
}) ;
当您在谷歌浏览器 48 中单击该按钮时,它会触发表单提交。
但是,如果您在 Firefox 43 中执行此操作,则不会提交表单。
在我看来,Firefox 的行为应该是正确的,但由于我对标准没有如此深入的了解,所以我真的不知道。
是行为错误还是有问题?
跟进:
我刚刚发现相同的测试用例但没有使用 jQuery 不会在两个浏览器中触发表单提交。
<form onsubmit="return false">
<button onclick="form.remove()">ok</button>
</form>
这可能是一个计时问题,因为Javascript中没有线程并发性。事件线程将始终按顺序运行,因此button
事件处理程序必须在form
事件处理程序启动之前完成。
我在这里瞎了眼。jQuery一定在Chrome中做了一些奇怪的繁琐事情。
跟进2:
这不是jQuery的问题。在jQuery错误跟踪器中,我被告知内联事件处理程序不遵循与addEventListener
附加的相同的规范,因此真正的功能等效代码应该是这样的:
<form>
<button>ok</button>
</form>
<script>
document.querySelector('form').addEventListener('submit',function(){ return false }) ;
document.querySelector('button').addEventListener('click',function(evt){ evt.target.form.remove() }) ;
</script>
这确实像jQuery版本一样。
您的第一个代码添加了一个 returnFalse
jQuery 事件侦听器:
$('form').submit(false);
在 jQuery 事件侦听器中,return false
等效于
event.stopPropagation();
event.preventDefault();
后者应阻止提交表格。
但是,在触发 submit
事件之前,请使用 $.fn.remove
。这不仅会从文档中删除表单,还会清理其 jQuery 数据,包括事件侦听器。
因此,当浏览器向窗体触发 submit
事件时,不会取消该事件。
然后浏览器的行为有所不同(演示(:
- 火狐浏览器不会提交已删除的表单
- Chrome 不在乎表单是否已被删除,无论如何都会提交
如果你不想删除jQuery数据,你应该使用vanilla-js方法而不是$.fn.remove
删除表单。
在第二个代码中,在 vanilla-js 事件处理程序中取消事件。
由于它不是 jQuery 数据,$.fn.remove
不会删除它,因此取消submit
事件并且不会提交表单。
在第三个代码中,使用vanilla-js方法删除表单,因此不会清理其jQuery数据。
这无关紧要,因为submit
事件侦听器也添加了 vanilla-js。
但是,该事件不会取消。这是因为,与 vanilla-js 事件处理程序和 jQuery 事件侦听器不同,vanilla-js 事件侦听器中返回的值被完全忽略。
因此,最后的结果与第一个代码相同,但它们并不等效。
如果要使用 vanilla-js 事件侦听器取消事件,则应使用
event.preventDefault();
这将使它的行为类似于第二个代码。
我认为它依赖于实现,不能保证相同的行为
当调用 $('form'(.remove(( 时,Chromium 和 Firefox 都不会调用由 $('form'(.submit(...( 安装的 form.onsubmit 处理程序。因此,这意味着表单在Chromium和Firefox中调用onsubmit之前被检查为已销毁(或实际已销毁(。
我认为 Chromium 不会在按下按钮发出处理默认提交操作时检查标记为已销毁的表单。但是 Chromium 会检查 prevent默认标志,其中按钮的默认操作是表单提交。因此,可以在 $('form'(.remove(( 之前或之后添加 event.preventDefault((。
在相反的火狐中,忽略阻止按钮按下事件的默认值,并将控制权传递给form.onsubmit。
因此,这两个浏览器关于 preventDefault 和 onsubmit 的行为完全相反。
就表单被标记为已销毁时表单提交的事实而言,可以想象软件设计在通信完成后而不是之前实际删除对象。但在我看来,这是错误。需要知道开发人员的想法。他们是否知道它,是这个错误或功能。
- 使用php或javascript从facebook相册URL中删除多余的部分
- RegEx删除空属性?例如,如果(class=“”||class=“”)移除;否则就下课
- 如何删除多行HTML排列中的空白
- 如何从rails中的代码中删除新行( )
- 删除对HTML元素的拖动
- 当图像转换为本地存储的DataURL时,EXIF被删除
- 按顺序添加和删除类
- iframe正在添加标签,需要删除它们
- 如何在HTML输入字段中添加不可删除的后缀
- addData()从最新图表中删除.js 2.1.3-怎么了
- 如何覆盖锚点元素's href目标,并在我点击转到目标javascript时删除其他错误
- 删除CKEditor工具栏按钮,但不删除功能
- 当浏览器上的后退按钮到达主页时,我需要删除Class
- 正在删除node.js中已验证的网站
- 正在从页面中删除iframe
- 如何从 HTML 查询中删除项目
- 如何在iOS应用程序中从Firebase中删除超过6小时的数据
- 未捕获的类型错误:无法读取属性'删除'的未定义
- 在事件冒泡阶段删除祖先
- 查找带有未选中复选框的元素并删除其祖先元素