javascript - 应用于多个元素时仅触发一次事件

标签 javascript html events dom-events addeventlistener

我正在使用纯 JS 动态创建表单。每当最后一个输入字段收到输入时,都应创建另一个空字段。另一方面,当最后一个字段为空时,最后一个字段也应该被删除。

HTML(用户输入前):

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

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

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

有人有解决办法吗?

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

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

最佳答案

对于所有想知道解决方案的人:

使用“insertAdjacentHTML”而不是“innerHTML”来动态创建元素。感谢 RajeshP 提供指向此有用答案的链接:Javascript AddEventListener Fires only once

关于javascript - 应用于多个元素时仅触发一次事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45168877/

相关文章:

JavaScript - 验证函数

javascript - 如何从java返回数据到javascript?

javascript - AngularJS:带有 ng-options 参数的指令中的下拉菜单

javascript - JS - 附加事件监听器并返回

events - eventCategory 和 eventAction 值

javascript - 防止歌剧鼠标手势

javascript - 使用箭头键导航表单字段

javascript - onclick函数javascript

javascript - 使用 jquery 切换对象的类

html - 如何在 html 中显示 colspan 和 rowspan 表?