应用于多个元素时,仅触发一次事件 [英] Event is triggered only once when applied to multiple elements

查看:108
本文介绍了应用于多个元素时,仅触发一次事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用普通JS动态创建表单。只要最后一个输入字段收到输入,就应该创建另一个空输入字段。另一方面,当最后一个字段在最后一个字段变为空之前应该被删除。

I am creating a form dynamically with plain JS. Whenever the last input field receives an input, another empty one should be created. On the other hand the last field should be removed when the one before the last becomes empty, too.

HTML(在用户输入之前):

HTML (before user input):

<div id="eventList" class="gap">
        <input id="event1" class="text bold eventBox" type="text" name="event1" placeholder="Ereignis 1" /> <br>
</div>

Javascript(之后实施;摘录中):

Javascript (implemented afterwards; in excerpts):

function addBox() {

    var boxes = document.getElementsByClassName("eventBox");

    var id = +getMaxID(boxes, "event") + +1;           // ID of input being created

    var list = document.getElementById("eventList");

    list.innerHTML = list.innerHTML + '<input id="event'+ id +'" class="text bold eventBox" type="text" name="event'+ id +'" placeholder="Ereignis '+ id +'" /> <br>';

    document.getElementById("event" + id).addEventListener("input", resizeEventList);

}

function delBox() {

    loadTexts();                // save current inputs

    var list = document.getElementById("eventList");

    document.getElementById("eventList").innerHTML = '';

    var id = 1;

    for (var i = 1; i < eventTexts.length; i++) {

        if (eventTexts[i].length > 0) {

            /* recreate box with its former input (if not empty) */

            document.getElementById("eventList").innerHTML = document.getElementById("eventList").innerHTML + '<input id="event'+ id +'" class="text bold eventBox" type="text" name="event'+ id +'" placeholder="Ereignis '+ id +'" value="' + eventTexts[i] + '"/> <br>';
            document.getElementById("event" + id).addEventListener("input", resizeEventList);

            id++;

        }

    }

    /* add new last empty input */

    document.getElementById("eventList").innerHTML = document.getElementById("eventList").innerHTML + '<input id="event'+ id +'" class="text bold eventBox" type="text" name="event'+ id +'" placeholder="Ereignis '+ id +'" value=""/> <br>';
    document.getElementById("event" + id).addEventListener("input", resizeEventList);

}

function resizeEventList(e) {

    if (typeof e != 'undefined') {

        var boxes = document.getElementsByClassName("eventBox");

        if (e.target.id == "event"+getMaxID(boxes, "event") && e.type == 'input') {

            /* input into last available box -> add an empty box */

                loadTexts();                // save current inputs

                senderID = e.target.id;     // remember ID of triggering element for resetting focus afterwards

                addBox();                   // add another box

                writeTexts();               // write former inputs back into boxes

                document.getElementById(senderID).focus();     // reset focus

        } else if (e.target.value.length == 0 && getID(e.target, "event") < getMaxID(boxes, "event")) {

            /* box before last box empty -> delete last empty box */

                senderID = e.target.id;     // remember ID of triggering element for resetting focus afterwards

                delBox();                   // delete all boxes and create X new boxes

                document.getElementById(senderID).focus();     // reset focus

        }

    }

}

var eventTexts = new Array();
var senderID;
document.getElementById("event1").addEventListener("input", resizeEventList);

现在的问题:当我将所有事件监听器仅应用于名为event1的输入时,代码按预期工作 - 在键入时添加输入,在空时删除一个输入,仅用于event1。当我将事件监听器也应用于动态创建的输入时(因为它应该并且在上面的代码中写入),输入事件仅在第一次输入时触发,包括event1。以下所有输入都不再记录。

The problem now: When I apply all Event Listeners only to the input named "event1", the code works as expected - adding an input when typing, removing one when empty, just for event1 only. When I apply the Event Listeners also to the dynamically created inputs (as it should be and is written in the code above), the input event is triggered only once at the first input ever made, including event1. All following inputs are not recorded anymore.

有人有解决方案吗?

谢谢,Jaspa

---完整代码--------------------

--- FULL CODE --------------------

<form id="planForm" class="top-margin" method="post" action="new.php?action=add">

    <div>
        <input class="text head bold" type="date" name="date" placeholder="Datum" value="<?php echo date("Y-m-d", time());?>" required /> <br>

        <div id="eventList" class="gap">

            <input id="event1" class="text bold eventBox" type="text" name="event1" placeholder="Ereignis 1" /> <br>

        </div>
    </div >

<input type="button" value="Speichern" onclick="save();" /  >

</form>

<script>

    function getID(elm, type) {
        if (typeof elm != 'undefined') {
            return elm.id.replace(type, "");
        } else {
            return "";
        }
    }

    function getMaxID(list, type) {

        currID = 0;
        max = 0;

        if (list != null && list.length > 0 && type != null) {
            for (var i=0; i < list.length; i++) {
                currID = getID(list[i], type);
                if ( currID > max ) {
                    max = currID;
                }
            }
        }

        return max;

    }

    function addBox() {

        var boxes = document.getElementsByClassName("eventBox");

        var id = +getMaxID(boxes, "event") + +1;           // ID of input being created

        var list = document.getElementById("eventList");

        list.innerHTML = list.innerHTML + '<input id="event'+ id +'" class="text bold eventBox" type="text" name="event'+ id +'" placeholder="Ereignis '+ id +'" /> <br>';

        document.getElementById("event" + id).addEventListener("input", resizeEventList);

        console.log(document.getElementById("event" + id));

    }

    function delBox() {

        loadTexts();                // save current inputs

        var list = document.getElementById("eventList");

        document.getElementById("eventList").innerHTML = '';

        var id = 1;

        for (var i = 1; i < eventTexts.length; i++) {

            if (eventTexts[i].length > 0) {

                /* recreate box with its former input (if not empty) */

                document.getElementById("eventList").innerHTML = document.getElementById("eventList").innerHTML + '<input id="event'+ id +'" class="text bold eventBox" type="text" name="event'+ id +'" placeholder="Ereignis '+ id +'" value="' + eventTexts[i] + '"/> <br>';
                document.getElementById("event" + id).addEventListener("input", resizeEventList);

                id++;

            }

        }

        /* add new last empty input */

        document.getElementById("eventList").innerHTML = document.getElementById("eventList").innerHTML + '<input id="event'+ id +'" class="text bold eventBox" type="text" name="event'+ id +'" placeholder="Ereignis '+ id +'" value=""/> <br>';
        document.getElementById("event" + id).addEventListener("input", resizeEventList);

    }

    function resizeEventList(e) {

        if (typeof e != 'undefined') {

            var boxes = document.getElementsByClassName("eventBox");

            if (e.target.id == "event"+getMaxID(boxes, "event") && e.type == 'input') {

                /* input into last available box -> add an empty box */

                    loadTexts();                // save current inputs

                    senderID = e.target.id;     // remember ID of triggering element for resetting focus afterwards

                    addBox();                   // add another box

                    writeTexts();               // write former inputs back into boxes

                    document.getElementById(senderID).focus();     // reset focus

            } else if (e.target.value.length == 0 && getID(e.target, "event") < getMaxID(boxes, "event")) {

                /* box before last box empty -> delete last empty box */

                    senderID = e.target.id;     // remember ID of triggering element for resetting focus afterwards

                    delBox();                   // delete all boxes and create X new boxes

                    document.getElementById(senderID).focus();     // reset focus

            }

        }

    }

    function loadTexts() {
        var boxes = document.getElementsByClassName("eventBox");

        for (var i=0; i < boxes.length; i++) {
            eventTexts[getID(document.getElementById(boxes[i].id), "event")] = boxes[i].value;
        }
    }

    function writeTexts() {
        var boxes = document.getElementsByClassName("eventBox");

        for (var i=0; i < boxes.length-1; i++) {
            document.getElementById(boxes[i].id).value = eventTexts[getID(boxes[i], "event")];
        }
    }

    var eventTexts = new Array();
    var senderID;
    document.getElementById("event1").addEventListener("input", resizeEventList);

</script>


推荐答案

对于每个想要了解解决方案的人:

For everybody who wants to know the solution:

使用insertAdjacentHTML代替innerHTML来动态创建元素。感谢RajeshP提供了这个有用答案的链接: Javascript AddEventListener仅触发一次

use "insertAdjacentHTML" instead of "innerHTML" to create elements dynamically. Thanks to RajeshP for giving a link to this helpful answer: Javascript AddEventListener Fires only once

这篇关于应用于多个元素时,仅触发一次事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆