在不同的框中按 Enter 时防止按钮上的 onclick 事件触发
Prevent onclick event on a button from firing when hitting Enter in a different box
我需要在 SE 编辑器的 #wmd-button-bar
中有一个用户输入字段以及一个按钮。用户可以在输入字段中输入一些数据,然后按下一个按钮来处理该数据。我正在使用用户脚本来实现这一点。我已经为它创建了一个单独的 MVCE,这里是它的 direct install link for Tampermonkey/Greasemonkey.
要重现该问题,请安装用户脚本。重新加载此页面,然后单击 "Edit"。您会注意到一个带有按钮的新空白输入框。将 "Edit summary" 框设为空白,将其留空,然后按 Enter。您的插入符现在不会提交答案框,而是会专注于新的空白输入框。
如果您在 "Question title" 框内按 Enter,也会发生同样的情况。
从 console.log
消息中,您会注意到按钮上有一个 MouseClick
事件!这不是预期的行为。事实上,这怎么可能呢?我们只是在 Edit summary 框中按下 Enter,甚至没有触及新的空白输入或其按钮。它是如何注册鼠标点击的?
如何解决这个问题?
注意: 按钮 onclick
处理程序中的 e.preventDefault();
是必需的。否则,当用户按下按钮来处理他们的输入数据时,答案框会提交自己。
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.innerHTML = "Button";
btn.onclick = function(e){
e.preventDefault();
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500)
我在 firefox 浏览器中尝试了以下代码,它按预期工作。
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.type = "button";
btn.innerHTML = "Button";
btn.onclick = function(e){
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500);
请注意我已经设置了 btn.type="button";
这确保表单不会被提交并且也被删除 e.preventDefault();
因为按钮现在永远不会提交表单。
请记住,默认情况下,如果您不为 button
元素提供 type
,那么它将表现得像 submit
按钮。
MouseClick
事件也被触发,因为在提交表单时点击事件在表单中出现的提交按钮上被触发。因为你有没有 type
属性的按钮,所以它就像一个提交按钮一样工作。所以 MouseClick
事件在您按下回车键时被触发(因为它正在提交表单)。
您可以通过从浏览器开发人员工具向 Save edits
提交按钮添加一个 onclick
处理程序来验证这一点,然后在文本字段上按回车键。
它的默认 HTML 行为。 form
里面的所有buttons
都是type="submit"
。默认情况下,在按下 enter
时,会单击 form
的最新按钮并调用它们的处理程序。为了解决这个问题,按钮是用 type="button"
.
创建的
console.log(document.querySelector("#a").type)
console.log(document.querySelector("#b").type)
console.log(document.querySelector("#c").type)
<form>
<input type="text">
<button id="a" onclick="console.log('a')">Submit type</button>
<button id="b" onclick="console.log('b')" type="button">Button type</button>
<input id="c" type="submit" value="Input Submit type">
</form>
您可以refer this了解<button>
和<input type="button">
的行为。
如果您只是像 document.querySelector("#box").children[1].type
这样在控制台中签入,它将显示为 submit
。
按钮,默认情况下,作为 submit
类型,除非明确指定(submit
(默认)/reset
/button
)。只是 运行 document.querySelector("#box").children[1].type=button
。您发现它按预期工作。
行为在跨浏览器中是相同的,并在 Firefox Nightly
(开发者版本)、Chrome
和 Safari
以及 works a little bit different in IE
.
中进行了测试
您还可以看到默认情况下点击 console.log(event.detail)
是 0
,因为它是在内部触发的。当用左键单击触发时,它将是 1
。 MDN Docs on click event
简短的答案是强制为您的按钮元素键入:
<button type="button"></button>
它默认为 type="submit"
,这就是它采取相应行动的原因。
我需要在 SE 编辑器的 #wmd-button-bar
中有一个用户输入字段以及一个按钮。用户可以在输入字段中输入一些数据,然后按下一个按钮来处理该数据。我正在使用用户脚本来实现这一点。我已经为它创建了一个单独的 MVCE,这里是它的 direct install link for Tampermonkey/Greasemonkey.
要重现该问题,请安装用户脚本。重新加载此页面,然后单击 "Edit"。您会注意到一个带有按钮的新空白输入框。将 "Edit summary" 框设为空白,将其留空,然后按 Enter。您的插入符现在不会提交答案框,而是会专注于新的空白输入框。
如果您在 "Question title" 框内按 Enter,也会发生同样的情况。
从 console.log
消息中,您会注意到按钮上有一个 MouseClick
事件!这不是预期的行为。事实上,这怎么可能呢?我们只是在 Edit summary 框中按下 Enter,甚至没有触及新的空白输入或其按钮。它是如何注册鼠标点击的?
如何解决这个问题?
注意: 按钮 onclick
处理程序中的 e.preventDefault();
是必需的。否则,当用户按下按钮来处理他们的输入数据时,答案框会提交自己。
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.innerHTML = "Button";
btn.onclick = function(e){
e.preventDefault();
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500)
我在 firefox 浏览器中尝试了以下代码,它按预期工作。
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.type = "button";
btn.innerHTML = "Button";
btn.onclick = function(e){
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500);
请注意我已经设置了 btn.type="button";
这确保表单不会被提交并且也被删除 e.preventDefault();
因为按钮现在永远不会提交表单。
请记住,默认情况下,如果您不为 button
元素提供 type
,那么它将表现得像 submit
按钮。
MouseClick
事件也被触发,因为在提交表单时点击事件在表单中出现的提交按钮上被触发。因为你有没有 type
属性的按钮,所以它就像一个提交按钮一样工作。所以 MouseClick
事件在您按下回车键时被触发(因为它正在提交表单)。
您可以通过从浏览器开发人员工具向 Save edits
提交按钮添加一个 onclick
处理程序来验证这一点,然后在文本字段上按回车键。
它的默认 HTML 行为。 form
里面的所有buttons
都是type="submit"
。默认情况下,在按下 enter
时,会单击 form
的最新按钮并调用它们的处理程序。为了解决这个问题,按钮是用 type="button"
.
console.log(document.querySelector("#a").type)
console.log(document.querySelector("#b").type)
console.log(document.querySelector("#c").type)
<form>
<input type="text">
<button id="a" onclick="console.log('a')">Submit type</button>
<button id="b" onclick="console.log('b')" type="button">Button type</button>
<input id="c" type="submit" value="Input Submit type">
</form>
您可以refer this了解<button>
和<input type="button">
的行为。
如果您只是像 document.querySelector("#box").children[1].type
这样在控制台中签入,它将显示为 submit
。
按钮,默认情况下,作为 submit
类型,除非明确指定(submit
(默认)/reset
/button
)。只是 运行 document.querySelector("#box").children[1].type=button
。您发现它按预期工作。
行为在跨浏览器中是相同的,并在 Firefox Nightly
(开发者版本)、Chrome
和 Safari
以及 works a little bit different in IE
.
您还可以看到默认情况下点击 console.log(event.detail)
是 0
,因为它是在内部触发的。当用左键单击触发时,它将是 1
。 MDN Docs on click event
简短的答案是强制为您的按钮元素键入:
<button type="button"></button>
它默认为 type="submit"
,这就是它采取相应行动的原因。