为什么只有 keydown 起作用,而 keyup 或 keypress 不起作用?
Why does only keydown work, and not keyup or keypress?
我有以下将待办事项添加到待办事项应用程序的代码:
HTML:
<div id="root">
<form class="todoForm">
<input class="input" placeholder="What do you need to do?" />
</form>
<div class="todos"></div>
<div class="footer">
<button class="All">All</button>
<button class="All">Active</button>
<button class="All">Completed</button>
</div>
</div>
CSS:
.todoForm {
margin-bottom: 20px;
}
.todos {
margin-bottom: 20px;
}
.todo {
margin-bottom: 10px;
}
.todoAndCheckBox {
display: flex
}
.checkBox {
border-radius: 50%;
outline: green;
}
JS:
class displayTodos {
constructor(root) {
this.root = root;
this.input = this.root.querySelector('.input');
this.form = this.root.querySelector('.todoForm');
// why does it work with keydown but not keyup
this.form.addEventListener('keydown', this.submitForm);
this.todos = this.root.querySelector('.todos');
this.state = {
todos: [
{
id: Math.random * 10000,
text: 'Pie'
},
{
id: Math.random * 10000,
text: 'Soy milk'
}
]
}
this.display();
}
submitForm = (e) => {
if(e.key === 'Enter') {
e.preventDefault();
const typed = this.input.value;
const newTodo = {
id: Math.random * 10000,
text: typed
}
const newTodos = [...this.state.todos, newTodo];
this.state.todos = newTodos;
this.display();
this.input.value = ''
}
}
display = () => {
while(this.todos.firstChild) {
this.todos.removeChild(this.todos.firstChild)
}
this.state.todos.forEach(todo => {
const todoAndCheckBox = document.createElement('div');
const todoDiv = document.createElement('div');
todoAndCheckBox.classList.add('todoAndCheckBox');
todoDiv.innerText = todo.text;
const checkBox = document.createElement('input');
checkBox.setAttribute('type', 'checkbox');
checkBox.classList.add('checkBox');
this.todos.appendChild(todoAndCheckBox);
todoAndCheckBox.appendChild(checkBox);
todoAndCheckBox.appendChild(todoDiv);
todoAndCheckBox.classList.add('todo')
})
}
}
const root = document.querySelector('#root');
const instance = new displayTodos(root);
在这一行:
this.form.addEventListener('keydown', this.submitForm);
我注意到,如果我将 keydown
更改为 keyup
或 keypress
,当我按回车键时,即使我有 e.preventDefault
,整个页面也会刷新。
我的问题是:
- 为什么 page/form 用
e.preventDefault
刷新?
- 为什么只有
keydown
有效(意味着它阻止表单刷新),但 keyup
或 keypress
无效?
提交表单事件已经由 keydown 触发,如果您在 keyup 上使用 e.preventDefault,则为时已晚。
您应该更改代码以绑定到 keydown 和 keyup。在 keydown 函数上,您可以调用 e.preventDefault(),在 keyup 函数上,您可以执行其他逻辑。
交替:
您可以使用以下代码完全禁用表单提交:
<form onsubmit="return false;">
然后在您确实希望它发生时手动触发表单提交:
document.forms[0].submit();
以上假设您只有一种形式 - 如果您现在或将来有多个选择器,您可能想使用 css 选择器:
document.querySelector("#formid").submit();
另请注意,提交按钮将不再有效,因此您需要将事件连接到它们的点击事件以通过相同的代码提交。
我有以下将待办事项添加到待办事项应用程序的代码:
HTML:
<div id="root">
<form class="todoForm">
<input class="input" placeholder="What do you need to do?" />
</form>
<div class="todos"></div>
<div class="footer">
<button class="All">All</button>
<button class="All">Active</button>
<button class="All">Completed</button>
</div>
</div>
CSS:
.todoForm {
margin-bottom: 20px;
}
.todos {
margin-bottom: 20px;
}
.todo {
margin-bottom: 10px;
}
.todoAndCheckBox {
display: flex
}
.checkBox {
border-radius: 50%;
outline: green;
}
JS:
class displayTodos {
constructor(root) {
this.root = root;
this.input = this.root.querySelector('.input');
this.form = this.root.querySelector('.todoForm');
// why does it work with keydown but not keyup
this.form.addEventListener('keydown', this.submitForm);
this.todos = this.root.querySelector('.todos');
this.state = {
todos: [
{
id: Math.random * 10000,
text: 'Pie'
},
{
id: Math.random * 10000,
text: 'Soy milk'
}
]
}
this.display();
}
submitForm = (e) => {
if(e.key === 'Enter') {
e.preventDefault();
const typed = this.input.value;
const newTodo = {
id: Math.random * 10000,
text: typed
}
const newTodos = [...this.state.todos, newTodo];
this.state.todos = newTodos;
this.display();
this.input.value = ''
}
}
display = () => {
while(this.todos.firstChild) {
this.todos.removeChild(this.todos.firstChild)
}
this.state.todos.forEach(todo => {
const todoAndCheckBox = document.createElement('div');
const todoDiv = document.createElement('div');
todoAndCheckBox.classList.add('todoAndCheckBox');
todoDiv.innerText = todo.text;
const checkBox = document.createElement('input');
checkBox.setAttribute('type', 'checkbox');
checkBox.classList.add('checkBox');
this.todos.appendChild(todoAndCheckBox);
todoAndCheckBox.appendChild(checkBox);
todoAndCheckBox.appendChild(todoDiv);
todoAndCheckBox.classList.add('todo')
})
}
}
const root = document.querySelector('#root');
const instance = new displayTodos(root);
在这一行:
this.form.addEventListener('keydown', this.submitForm);
我注意到,如果我将 keydown
更改为 keyup
或 keypress
,当我按回车键时,即使我有 e.preventDefault
,整个页面也会刷新。
我的问题是:
- 为什么 page/form 用
e.preventDefault
刷新? - 为什么只有
keydown
有效(意味着它阻止表单刷新),但keyup
或keypress
无效?
提交表单事件已经由 keydown 触发,如果您在 keyup 上使用 e.preventDefault,则为时已晚。 您应该更改代码以绑定到 keydown 和 keyup。在 keydown 函数上,您可以调用 e.preventDefault(),在 keyup 函数上,您可以执行其他逻辑。
交替:
您可以使用以下代码完全禁用表单提交:
<form onsubmit="return false;">
然后在您确实希望它发生时手动触发表单提交:
document.forms[0].submit();
以上假设您只有一种形式 - 如果您现在或将来有多个选择器,您可能想使用 css 选择器:
document.querySelector("#formid").submit();
另请注意,提交按钮将不再有效,因此您需要将事件连接到它们的点击事件以通过相同的代码提交。