我尝试构建一个倒数计时器,该计时器具有 3 个控制计时器的按钮。 3 个按钮开始、取消和暂停。计时器只是文本输入字段,您可以在其中输入一个正整数。
我必须使用核心 JavaScript,而不是 jQuery
开始按钮:开始倒计时到 0
取消按钮:重新显示默认输入值
暂停按钮:将计时器保持在当前值,直到单击开始按钮,返回正常操作。
我对这 3 个提交按钮使用了 addEventListener 方法,但是当我单击其中任何一个按钮时,它们都同时被触发。我尝试放置 e.preventDefault 和 e.stopImmediatePropagation,但这并没有真正的帮助。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Countdown</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul {
list-style-type: none;
background-color: #03f72c;
}
.invalid {
background-color: #c71f1f;
}
</style>
</head>
<body>
<div>
<h1>Countdown</h1>
<form id="myForm">
<div>
<label for="posint">Timer:</label>
<input type="text" id="input" name="posint">
</div>
<div class="controller">
<div class="button">
<input id="start" type="submit" value="Start"></input>
</div>
<div class="button">
<input id="pause" type="submit" value="Pause"></input>
</div>
<div class="button">
<input id="cancel" type="submit" value="Cancel"></input>
</div>
</div>
<div id="errormsgs">
<ul id="warning">
<h3>Checklist</h3>
<li id="posint_err"></li>
</ul>
</div>
</form>
</div>
<script>
function formControl() {
// getting input value
var input = document.getElementById("input");
var myForm = document.getElementById("myForm");
myForm.addEventListener("submit", start);
myForm.addEventListener("submit", cancel);
myForm.addEventListener("submit", pause);
// regex validate
var containInt = /^-?[0-9]\d*$/;
// ======== UI text ========
var posint_err = "It must contain only an integer greater than 0";
var expiredMsg = "expired";
function render(target, content, attributes) {
for (const key in attributes) {
target.setAttribute(key, attributes[key]);
}
target.value = content;
}
// Select All function
function selectAll() {
input.focus();
input.setSelectionRange(0, input.value.length);
}
// UI state
const state = {
defaultValue: "",
failed() {
document.getElementById("warning").classList.add("invalid");
document.getElementById("posint_err").innerHTML = posint_err;
document.getElementById("posint_err").style.display = "block";
},
success() {
document.getElementById("errormsgs").style.display = "none";
},
clear() {
document.getElementById("posint_err").style.display = "none";
},
}
// start function
function start(e) {
if (parseInt(input.value) <= 0 || (!(input.value.match(containInt)))) {
state.clear()
state.failed();
selectAll();
e.preventDefault();
e.stopImmediatePropagation();
return false
} else {
// success case
var inputValue = parseInt(input.value);
state.defaultValue = inputValue;
e.preventDefault();
e.stopImmediatePropagation();
state.success();
input = setInterval(countdown, 1000);
// Countdown function()
function countdown() {
inputValue--;
render(document.getElementById("input"), inputValue)
if (inputValue <= 0) {
clearInterval(input);
render(document.getElementById("input"), expiredMsg)
}
}
return false
}
}
// cancel function
function cancel(e) {
// e.stopImmediatePropagation();
// console.log(state.defaultValue)
e.preventDefault();
e.stopImmediatePropagation();
clearInterval(input);
render(input, state.defaultValue);
return false
}
// cancel function
function pause(e) {
e.preventDefault();
e.stopImmediatePropagation();
console.log('pause')
return false
}
}
window.onload = function () {
formControl();
};
</script>
</body>
</html>
最佳答案
不要将监听器附加到 form
- 而是将它们附加到 input
。 (此外,从这些输入中删除 type="submit"
- 使用 type="button"
来代替它以您想要的方式显示)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Countdown</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ul {
list-style-type: none;
background-color: #03f72c;
}
.invalid {
background-color: #c71f1f;
}
</style>
</head>
<body>
<div>
<h1>Countdown</h1>
<form id="myForm">
<div>
<label for="posint">Timer:</label>
<input type="text" id="input" name="posint">
</div>
<div class="controller">
<div class="button">
<input type="button" id="start" value="Start"></input>
</div>
<div class="button">
<input type="button" id="pause" value="Pause"></input>
</div>
<div class="button">
<input type="button" id="cancel" value="Cancel"></input>
</div>
</div>
<div id="errormsgs">
<ul id="warning">
<h3>Checklist</h3>
<li id="posint_err"></li>
</ul>
</div>
</form>
</div>
<script>
function formControl() {
// getting input value
var input = document.getElementById("input");
var myForm = document.getElementById("myForm");
document.querySelector('#start').addEventListener("click", start);
document.querySelector('#cancel').addEventListener("click", cancel);
document.querySelector('#pause').addEventListener("click", pause);
// regex validate
var containInt = /^-?[0-9]\d*$/;
// ======== UI text ========
var posint_err = "It must contain only an integer greater than 0";
var expiredMsg = "expired";
function render(target, content, attributes) {
for (const key in attributes) {
target.setAttribute(key, attributes[key]);
}
target.value = content;
}
// Select All function
function selectAll() {
input.focus();
input.setSelectionRange(0, input.value.length);
}
// UI state
const state = {
defaultValue: "",
failed() {
document.getElementById("warning").classList.add("invalid");
document.getElementById("posint_err").innerHTML = posint_err;
document.getElementById("posint_err").style.display = "block";
},
success() {
document.getElementById("errormsgs").style.display = "none";
},
clear() {
document.getElementById("posint_err").style.display = "none";
},
}
// start function
function start(e) {
if (parseInt(input.value) <= 0 || (!(input.value.match(containInt)))) {
state.clear()
state.failed();
selectAll();
e.preventDefault();
e.stopImmediatePropagation();
return false
} else {
// success case
var inputValue = parseInt(input.value);
state.defaultValue = inputValue;
e.preventDefault();
e.stopImmediatePropagation();
state.success();
input = setInterval(countdown, 1000);
// Countdown function()
function countdown() {
inputValue--;
render(document.getElementById("input"), inputValue)
if (inputValue <= 0) {
clearInterval(input);
render(document.getElementById("input"), expiredMsg)
}
}
return false
}
}
// cancel function
function cancel(e) {
console.log('cancel');
// e.stopImmediatePropagation();
// console.log(state.defaultValue)
e.preventDefault();
e.stopImmediatePropagation();
clearInterval(input);
render(input, state.defaultValue);
return false
}
// cancel function
function pause(e) {
e.preventDefault();
e.stopImmediatePropagation();
console.log('pause')
return false
}
}
window.onload = function () {
formControl();
};
</script>
</body>
</html>
关于javascript - 多个 AddEventListener 表单提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50126955/