【问题标题】:How to invoke a function on pressing the "Enter" key如何在按下“Enter”键时调用函数
【发布时间】:2019-01-02 21:09:33
【问题描述】:

这是我的应用程序的 JSFiddle 链接:https://jsfiddle.net/kdowdell24/a9t7b23c/2/

document.getElementById("add-button").addEventListener("click", function() {

function createNewItem() {
    //creates div element with a class of "input-item"
    let itemContainer = document.createElement("div");
    itemContainer.classList.add("input-item");

    //creates input element and sets type attribute to "checkbox"
    let checkBoxInput = document.createElement("input");
    checkBoxInput.setAttribute("type", "checkbox");
    checkBoxInput.classList.add("check-box");

    //creates input element and sets "type" attribute to "text"
    let textInput = document.createElement("input");
    textInput.setAttribute("type", "text");

    //creates button element and sets "class" to "delete-button" and "type" to "button"
    let deleteButton = document.createElement("button");
    deleteButton.classList.add("delete-button");
    deleteButton.setAttribute("type", "button");

    //creates Font Awesome "X" icon and adds "fas" and "fa-times" classes
    let xIcon = document.createElement("i");
    xIcon.classList.add("fas");
    xIcon.classList.add("fa-times");

    //adds a div to form
    let formElement = document.getElementById("shopping-list");
    formElement.appendChild(itemContainer);

    //adds checkbox, input, and "delete-button" to div
    itemContainer.appendChild(checkBoxInput);
    itemContainer.appendChild(textInput);
    itemContainer.appendChild(deleteButton);

    //adds "X" icon to button
    deleteButton.appendChild(xIcon);

    //removes checkbox, input and deleteButton from form
    deleteButton.addEventListener("click", function() {
        checkBoxInput.remove();
        textInput.remove();
        deleteButton.remove();
        itemContainer.remove();

    });
};

createNewItem();


//Adds new item after pressing Enter key
let itemList = document.querySelectorAll("input[type=text]");
for (var i = 0; i < itemList.length; i++) {
    addEventListener("keypress", function(e) {
        if (e.key === "Enter") {
            createNewItem();
            console.log("New item created!");
        }
    })
}

});

//Removes all content from list after pressing Clear All button
document.getElementById("clear-button").addEventListener("click", function() {
let listContent = document.querySelectorAll(".input-item");
for (var i = 0; i < listContent.length; i++) {
    listContent[i].remove();
}

})

我遇到的问题是这段代码:

//Adds new item after pressing Enter key
let itemList = document.querySelectorAll("input[type=text]");
for (var i = 0; i < itemList.length; i++) {
    addEventListener("keypress", function(e) {
        if (e.key === "Enter") {
            createNewItem();
            console.log("New item created!");
        }
    })
}

发生的情况是,当我在列表项的文本框中按 Enter 时,它会添加多个条目,而不仅仅是一个。我想要完成的是在按下 Enter 后只在当前条目下方创建一个条目。

【问题讨论】:

  • 您的侦听器正在运行多次,因为您将它保存在 for loop 中。你到底需要在这里做什么?也请在您的问题中发布createNewItem() 的代码。
  • 嘿,@KrisD 您需要将 addEventListener 附加到某些东西上。它只是坐在那里。这可能会导致它附加到文档或窗口,这意味着您在同一个节点上有很多监听。
  • 我要做的是让用户在文本框中按 Enter 后只创建一个额外的列表项。现在,它会在按 Enter 后一次创建多个。
  • 这是因为所谓的事件冒泡。由于您将其附加到文档中,因为您没有清楚地说明事件侦听器将附加到您的内容,因此存在潜在的内存泄漏。这只是意味着您需要指定要将其附加到的输入。

标签: javascript for-loop if-statement event-listener enter


【解决方案1】:

如果您想在按下 ENTER 键时添加一个新复选框,只需更改以下内容:

let itemList = document.querySelectorAll("input[type=text]");
for (var i = 0; i < itemList.length; i++) {
    addEventListener("keypress", function(e) {
        if (e.key === "Enter") {
            createNewItem();
            console.log("New item created!");
        }
    })
}

到这里:

document.addEventListener("keypress", function(e) {
  if (e.key === "Enter" && (document.activeElement.tagName.toLowerCase() !== 'button')) {
    createNewItem();
    console.log("New item created!");
  }
});

我分叉了你当前的 jsFiddle 并在这里使用了上面的代码:https://jsfiddle.net/AndrewL64/3fcgpxrL/30/

感谢@Moosecouture,他提到使用document.activeElement 来防止在按键期间元素处于焦点时出现不必要的调用。

【讨论】:

  • 但请注意,回车键也会调用页面的其他元素。因此,如果您刚刚单击 + 按钮并且焦点仍在该按钮上,则单击 Enter 键将调用 + 按钮以及上面的函数,从而同时创建两个复选框。
  • 这成功了!尽管我确实看到了您的观点,即当 + 成为焦点时会创建两个条目。我还在学习 JavaScript,所以我会在学习更多内容时尝试微调我的项目。
  • 很高兴我能帮到人。如果它帮助您解决问题,请将此标记为正确答案。同时,我会尝试修改上面的代码,看看是否能找到解决 + focus 问题的方法,如果找到了,我会告诉你。
  • @KrisD 感谢 Moosecouture 的评论,我已经编辑了上面的代码以及 jsFiddle 以防止在按键期间元素处于焦点时出现不需要的调用。
  • @AndrewL 更新后的代码可以防止不必要的调用,但它也会在文本框输入处于活动状态时取消列表项的 Enter 功能。
【解决方案2】:

试试这个,小心输入任何输入都会触发一个新项目,所以使用选项卡导航

//Adds new item after pressing Enter key
function keyDownListener (e) {
  if (e.keyCode === 13) {
      e.preventDefault();
      createNewItem();
      addListeners()
      console.log("New item created!");
  }
}
function addListeners() {
  let itemList = document.querySelectorAll("input[type=text]");
  for (var i = 0; i < itemList.length; i++) {
    try {
      itemList[i].removeEventListener("keydown", keyDownListener)
    } catch (error) {

    }
    itemList[i].addEventListener("keydown", keyDownListener)
  }
}

另外,人们建议使用.keyCode,即13,而不是.key

【讨论】:

  • 这解决了添加多个条目的问题,但是 Enter 功能似乎仅适用于添加的第一个条目,并且不会扩展到新创建的条目。
  • 这里应该已经修复了,我完全测试过了。
  • 哦,好吧...让我试试别的。
  • 所以,这个更新应该会有所帮助。您需要做的是识别添加的新项目或从旧输入中删除事件侦听器,然后再次添加它们,以便每次确保每个输入都有侦听器。
  • 这应该解决而不是像 AndrewL 所示的那样将其保留在文档级别。如果您使用 AndrewL 的方法,我建议您在按“Enter”时检查您关注的内容。这样使用document.activeElement不会触发他提到的问题。
猜你喜欢
  • 1970-01-01
  • 2020-06-25
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 2014-05-30
相关资源
最近更新 更多