【发布时间】:2019-07-25 12:51:10
【问题描述】:
注意 所以我实际上在写出问题的同时设法解决了这个问题,但我想无论如何我都会发帖以防它帮助其他人(在 Stack Overflow 上的简短搜索表明,似乎没有其他人问过完全相同的问题)
所以我有一个带有通过 JavaScript 处理的 Web 组件的表单,如下所示:
<form id="myform">
<input type="text" value="example" tabindex="1" />
<web-component tabindex="2"></web-component>
<input type="submit" tabindex="3" />
</form>
<script>
let form = document.getElementById('myform');
form.addEventListener('submit' (e) => {
e.preventDefault();
console.log('Form is posting');
// Handle form stuff here
})
</script>
对于我的 Web 组件,我希望能够在将表单切换到 Web 组件并按“Enter”时“提交”表单,这样我在 Web 组件中就有了以下处理程序:
class WebComponent extends HTMLElement {
constructor() {
...
let form = this.closest('form');
this.addEventListener('keydown', (e) => {
if(form && e.code === 'Enter') form.submit();
})
}
}
我遇到的问题是form.submit() 提交了表单,但没有触发被监控的事件,导致form 事件处理程序无法运行,并且表单只是在没有任何 JS 验证的情况下发布。我让表单工作的第一个想法是将表单提交函数更改为命名函数,例如:
form.addEventListener('submit', handleFormSubmission);
myComponent.addEventListener('keydown', (e) => {
if(e.code === 'Enter') handleFormSubmission();
})
但是这里的问题是,Web 组件不一定能用于多个表单,或者需要在每次调用它时添加一个事件处理程序,以确保它与与形式。这必须在组件之外完成,并且确实降低了可读性。
我考虑的另一个选项是在表单中搜索 input[type=submit] 或 button[type=submit] 并触发点击,但这对我来说似乎有些笨拙。
经过一番搜索,我发现了dispatchEvent,它会触发submit 事件,而不是简单地触发submit(),如下所示:
class WebComponent extends HTMLElement {
constructor() {
...
let form = this.closest('form');
this.addEventListener('keydown', (e) => {
if(form && e.code === 'Enter') form.dispatchEvent(new Event('submit'));
})
}
}
现在我 非常 接近 - submit 处理程序和 console.log 触发,但 e.preventDefault() 不受尊重,这意味着如果我的 JS 验证想要终止出于任何原因提交,它不能...默认情况下。
更多的搜索(即实际上很费心阅读规范,而不是全速前进并在墙上扔泥看看有什么粘着)我意识到Event 构造函数需要一个可选对象进行设置,这样您就可以拥有(例如)new Event('submit', {bubbles: true, cancelable: true})。最后,它起作用了:
let form = document.getElementById('myform');
form.addEventListener('submit' (e) => {
e.preventDefault();
console.log('Form is posting');
// Handle form stuff here
});
class WebComponent extends HTMLElement {
constructor() {
...
let form = this.closest('form');
this.addEventListener('keydown', (e) => {
if(form && e.code === 'Enter') form.dispatchEvent(new Event('submit', {cancelable: true}));
})
}
}
【问题讨论】:
标签: javascript events submit preventdefault