javascript - 多个 AddEventListener 表单提交

标签 javascript html forms dom web

我尝试构建一个倒数计时器,该计时器具有 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/

相关文章:

javascript - Dojo JsonRest Promise -- 异步调用的顺序

javascript - 将 JavaScript 评估到 WKWebView 中以获取视频 URL 不起作用

css - 里面有float属性的div在调整的时候中心div没有调整

javascript - 单击按钮时将时间戳传递给表单

javascript - 点击功能有问题

forms - Delphi:来自非模态二次形式的 'ShowModal'

asp.net - 如何禁用表单例份验证

javascript - 如何让 iframe 中的网页加载自己的 JavaScript?

javascript - 控制多个 Canvas 动画

php - 创建 PHP 多维关联数组的 Javascript 版本