AddEventListener 根据看似不相关的变量多次侦听点击。Javascript、电子JS

AddEventListener listening for click going off multiple times depending on seemingly unrelated variables. Javascript, ElectronJS

提问人:Alex-GR 提问时间:11/17/2023 最后编辑:Alex-GR 更新时间:11/17/2023 访问量:34

问:

我正在构建一个基于 ElectronJS 的简单桌面应用程序。该应用程序的目的是通过与我创建的图形界面交互来生成mySQL数据库。当我向现有表添加新列时,问题就出现了。 每次我尝试添加一列时,都会添加意想不到的数量。但是,我似乎看到了这种模式,每次我从列创建者界面返回到表时,当我在任何其他表中重新输入任何其他列创建者时添加的列数都会增加一。

例如,如果我在表格中输入列创建者三次,并且我将保留它三次,则第 4 次尝试中添加的列数将是 4。

以下是我创建新表的方法:

addTable.addEventListener('click', () => {

    // Create a container for the table
    const tableContainer = document.createElement('div');
    tableContainer.setAttribute('class', 'tableContainer')
    tableContainer.setAttribute('id', `tableContainer_${numberOfTables}`)
    newTableContainer.appendChild(tableContainer);

    /* Input field type text - table name */
    const tableName = document.createElement('input');
    tableName.setAttribute('id', `tableName_${numberOfTables}`);
    tableName.setAttribute('class', 'input');
    tableName.setAttribute('type', 'text');
    tableName.setAttribute('placeholder', 'Table name: ');
    tableContainer.appendChild(tableName);

    /* Input field type button - edit */
    const addColumns = document.createElement('input');
    addColumns.setAttribute('id', `addColumnsButton_${numberOfTables}`);
    addColumns.setAttribute('class', 'add-columns-button table-creator-button');
    addColumns.setAttribute('type', 'button');
    addColumns.setAttribute('data-table-number', numberOfTables)
    addColumns.setAttribute('value', 'Add columns');
    tableContainer.appendChild(addColumns);

    // Attach click event listener to the new add columns button
    addColumns.addEventListener('click', () => {
        // Get the value of the data-table-number attribute
        let buttonNumber = addColumns.getAttribute('data-table-number');
        // Use the buttonNumber to identify the associated tableName
        let tableToEdit = document.getElementById(`tableName_${buttonNumber}`);

        if (tableToEdit) {
            console.log("debug 1")
            editTheTableColums(tableToEdit, buttonNumber);
        }
    });


    /* Input field type button - delete the table */
    const deleteTheTable = document.createElement('input');
    deleteTheTable.setAttribute('id', `deleteTheTableButton_${numberOfTables}`);
    deleteTheTable.setAttribute('class', 'delete-the-table-button table-creator-button');
    deleteTheTable.setAttribute('type', 'button');
    deleteTheTable.setAttribute('value', 'Delete this table');
    deleteTheTable.setAttribute('data-table-number', numberOfTables)
    tableContainer.appendChild(deleteTheTable);

    // Attach click event listener to the new delete button
    deleteTheTable.addEventListener('click', () => {
        // Get the value of the data-table-number attribute
        let buttonNumber = deleteTheTable.getAttribute('data-table-number');
        // Use the buttonNumber to identify the associated tableContainer
        let tableToDelete = document.getElementById(`tableContainer_${buttonNumber}`);

        if (tableToDelete) {
            tableToDelete.parentNode.removeChild(tableToDelete);
        }
    });


    numberOfTables++;
});

基本上,它是一个不那么复杂的createElement脚本,每次单击按钮都会运行。

因此,在我看到代码正常工作并且相对安全之后,对于我测试的内容,我打算使用相同的方法在创建的表中创建列。通过UI完成的方式是,当您创建表格时,每个表格都有自己的按钮,该按钮将显示“添加列”,如果您单击该按钮,表格将从屏幕上消失,您可以通过单击屏幕顶部的特定按钮来创建新列,每次单击“添加列”按钮后都会出现该按钮。

这里是第一个函数:

/* Handle adding columns to the tables */
function editTheTableColums(tableToEdit, buttonNumber) {
    console.log("debug 2")
    let numberOfColumns = 0;

    /* Check if the table name is not empty */
    if (tableToEdit.value.trim() != "") {

        mainH1.innerHTML = `Adding columns to the table <i>${tableToEdit.value}</i>`;

        /* Chnage the page */
        newTableContainer.style.display = "none";
        editColumnsContainer.style.display = "inline";

        /* Chnage the button visibility */
        addTable.style.display = "none";
        backToMainMenu.style.display = "none";
        backToTheTableCreator.style.display = "inline";
        addColumn.style.display = "inline";
        confirm.style.display = 'inline';

        //Create a new container assosiated with the table
        const tableColumns = document.createElement('div');
        tableColumns.setAttribute('class', 'tableColumns')
        tableColumns.setAttribute('id', `tableColumns_${buttonNumber}`)
        editColumnsContainer.appendChild(tableColumns);

        let currentTable = document.getElementById(`tableColumns_${buttonNumber}`)

        // Loop through the children elements and hide them
        for (let i = 0; i < editColumnsContainer.children.length; i++) {
            editColumnsContainer.children[i].style.display = "none";
        }

        currentTable.style.display = "inline";


        /* Column creator */
        addColumn.addEventListener('click', () => {
            addColumnFunc(buttonNumber, numberOfColumns, currentTable);
        }); // sth broke here
          
    }
}

下面是处理列的另外两个函数:

const addColumnFunc = function(buttonNumber, numberOfColumns, currentTable) {
    
    console.log("debug 3")
    const currentButtonNumber = buttonNumber;

    // Create a container for the column
    const columnContainer = document.createElement('div');
    columnContainer.setAttribute('class', 'columnContainer')
    columnContainer.setAttribute('id', `columnContainer_${numberOfColumns}_${currentButtonNumber}`)
    currentTable.appendChild(columnContainer);

    let currentColumnContainer = document.getElementById(`columnContainer_${numberOfColumns}_${currentButtonNumber}`);

    /* Input field type text - column name */
    const columnName = document.createElement('input');
    columnName.setAttribute('id', `columnName_${numberOfColumns}_${currentButtonNumber}`);
    columnName.setAttribute('class', 'input column-name');
    columnName.setAttribute('type', 'text');
    columnName.setAttribute('placeholder', 'Column name: ');
    currentColumnContainer.appendChild(columnName);

    /* Input field type button - delete the column */
    const deleteTheColumn = document.createElement('input');
    deleteTheColumn.setAttribute('id', `deleteTheColumnButton_${numberOfColumns}_${currentButtonNumber}`);
    deleteTheColumn.setAttribute('class', 'delete-the-column-button column-creator-button');
    deleteTheColumn.setAttribute('type', 'button');
    deleteTheColumn.setAttribute('value', 'Delete');
    deleteTheColumn.setAttribute('data-column-number', numberOfColumns)
    currentColumnContainer.appendChild(deleteTheColumn);

    // Attach click event listener to the new delete button
    deleteTheColumn.addEventListener('click', () => {
        // Get the value of the data-column-number attribute
        let buttonNumber = deleteTheColumn.getAttribute('data-column-number');
        // Use the buttonNumber to identify the associated columnContaine
        let columnToDelete = document.getElementById(`columnContainer_${numberOfColumns}_${buttonNumber}`);

        if (columnToDelete) {
            columnToDelete.parentNode.removeChild(columnToDelete);
        }
    });


    numberOfColumns++;
};


/* Handle going back from column creator to the table creator */
backToTheTableCreator.addEventListener('click', () => {
    console.log("back")

    mainH1.innerHTML = `Editing ${databaseName}`;

    addColumn.removeEventListener('click', addColumnFunc);

    /* Chnage the page */
    newTableContainer.style.display = "inline";
    editColumnsContainer.style.display = "none";

    /* Chnage the button visibility */
    addTable.style.display = "inline";
    backToMainMenu.style.display = "inline";
    backToTheTableCreator.style.display = "none";
    document.getElementById("add-column").style.display = "none";
    confirm.style.display = 'none';

});

第一次添加列将按预期工作,将添加一列,但是如果我退出并进入任何其他表,则会出现两列,并且每次退出都会增加要添加的列数一列。

以下是启动应用程序后的控制台日志输出,创建了三个表并一次浏览一个表,向每个表添加一列(尝试仅向每个表添加一列)

debug 1
temp.js:132 debug 2
temp.js:179 debug 3
temp.js:226 back
temp.js:91 debug 1
temp.js:132 debug 2
2temp.js:179 debug 3
temp.js:226 back
temp.js:91 debug 1
temp.js:132 debug 2
3temp.js:179 debug 3

代码可能看起来有点凌乱或评论不专业,我真的很抱歉,可以肯定地说我是初学者。我也很确定这个问题可能会被问得很糟糕,但英语不是我的第一语言,所以请原谅我的任何错误。我也想原谅自己提供了这么多代码,但我不确定其中的哪一部分可能会导致问题。

编辑一个 - 添加 event.stopPropagation();方法不能解决问题。非常感谢@ElvisAdomnica指出这是一个可能的解决方案

JavaScript 电子 事件处理 addeventlistener createelement

评论

0赞 Elvis Adomnica 11/17/2023
我只是快速浏览了代码,您似乎有嵌套元素,但点击事件没有调用event.stopPropagation();
0赞 Alex-GR 11/17/2023
@ElvisAdomnica 是的,你是对的,我快速浏览了一些关于它是什么的信息,这似乎是合理的,我会修复它并检查问题是否仍然存在。完成后,我将更新问题
0赞 Arkellys 11/25/2023
我认为如果您创建一个重现问题的片段,会更容易为您提供帮助。

答: 暂无答案