简体   繁体   English

事件应用于多个元素时只触发一次

[英]Event is triggered only once when applied to multiple elements

I am creating a form dynamically with plain JS.我正在使用纯 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 (before user input): HTML(在用户输入之前):

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

Javascript (implemented afterwards; in excerpts): Javascript(之后实现;在摘录中):

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);

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.现在的问题:当我将所有事件侦听器仅应用于名为“event1”的输入时,代码按预期工作 - 键入时添加一个输入,空时删除一个输入,仅适用于 event1。 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.当我将事件侦听器也应用于动态创建的输入时(它应该是并且写在上面的代码中),输入事件仅在第一次输入时触发一次,包括 event1。 All following inputs are not recorded anymore.不再记录所有以下输入。

Does anybody have a solution?有人有解决方案吗?

--- 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:对于想知道解决方案的每个人:

use "insertAdjacentHTML" instead of "innerHTML" to create elements dynamically.使用“insertAdjacentHTML”而不是“innerHTML”来动态创建元素。 Thanks to RajeshP for giving a link to this helpful answer: Javascript AddEventListener Fires only once感谢 RajeshP 提供了这个有用答案的链接: Javascript AddEventListener Fires only once

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM