簡體   English   中英

為什么只有 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更改為keyupkeypress ,當我按下回車鍵時,即使我有e.preventDefault ,整個頁面也會刷新。 我的問題是:

  1. 為什么使用e.preventDefault刷新頁面/表單?
  2. 為什么只有keydown起作用(意味着它停止刷新表單),而不是keyupkeypress

提交表單事件已經被keydown觸發了,如果你在keyup上使用e.preventDefault,那就太晚了。 您應該更改代碼以綁定到 keydown 和 keyup。 在 keydown function 上,您可以調用 e.preventDefault(),在 keyup function 上,您可以執行其他邏輯。

或者

您可以使用以下代碼完全禁用表單提交:

<form onsubmit="return false;">

然后在您真正希望它發生時手動觸發表單提交:

document.forms[0].submit();

以上假設您只有一種形式 - 如果您現在或將來有多個,您可能想要使用 css 選擇器:

document.querySelector("#formid").submit();

另請注意,提交按鈕將不再起作用,因此您需要將事件連接到其點擊事件以通過相同的代碼提交。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM