【问题标题】:How would you go about grabbing an <input> element's value when that <input> element is inside of a Nodelist?当 <input> 元素在 Nodelist 中时,你将如何获取 <input> 元素的值?
【发布时间】:2020-05-21 23:32:18
【问题描述】:

我目前正在为客户的问卷调查应用程序“导出到 csv”,其中所有用户输入数据都被捕获并写入 .csv 文件。

在由 getElementsByTagName() 捕获的 HTML 集合中同时存在 &lt;input&gt;&lt;select&gt; 元素。下面是我的 HTML 外观的 sn-p:

 <tr>
    <td><input type="text" id="person1" name="person1"></td>
    <td>
        <select name="person1_lang1_primary" id="person1_lang1_select">
            <option value=""></option>
            <option value="english">English</option>
            <option value="Spanish">Spanish</option>
            <option value="other1">Other1 - specify below</option>
            <option value="other2">Other2 - specify below</option>
            <option value="other3">Other3 - specify below</option>
            <option value="other4">Other4 - specify below</option>
        </select>
    </td>
 <tr>

解决这一切的功能是:

class TableCSVExporter {
constructor (table, includeHeaders = true) {

    this.table = table;
    this.rows = Array.from(table.querySelectorAll("tr"));

    if(!includeHeaders && this.rows[0].querySelectorAll("th").length) {
        this.rows.shift();
    }


}

convertToCSV() {
    const lines = [];
    const numCols = this._findLongestRowLength();

    for(const row of this.rows) {
        let line = "";

        for(let i = 0; i < numCols; i++) {
            if (row.children[i] !== undefined) {
                line += TableCSVExporter.parseCell(row.children[i]);
            }

            line += (i !== (numCols - 1)) ? "," : "";
        }

        lines.push(line);
        // console.log(row);
    }

    return lines.join("\n");
}

_findLongestRowLength() {
    return this.rows.reduce((l, row) => row.childElementCount > l ? row.childElementCount : l, 0);
}

static parseCell (tableCell) {

    let input_elements = tableCell.getElementsByTagName("input");
    let select_elements = tableCell.getElementsByTagName("select");

    let inputArray = Array.from(input_elements);
    let selectArray = Array.from(select_elements);

    let elementsArray = [...inputArray, ...selectArray];
    let parsedValue = [...elementsArray];





    // Replace all double quotes with two double quotes
    parsedValue = parsedValue.replace(/"/g, `""`);

    // If value contains comma, new-line or double-quote, enclose in double quotes
    parsedValue = /[", \n]/.test(parsedValue) ? `"${parsedValue}"` : parsedValue;



    inputArray.forEach(element => console.log(element.value));
    selectArray.forEach(element => console.log(element.value));

    elementsArray.forEach(element => console.log(element.value));


    return parsedValue;

}

}

HTML 文件中还有一个&lt;script&gt;,其中包含以下内容:

<script>
    const primaryInputByPerson = document.getElementById("primaryInputByPerson");
    const btnExportCSV = document.getElementById("btnExportToCSV");


    btnExportCSV.addEventListener("click", () => {
        const exporter = new TableCSVExporter(primaryInputByPerson);
        const csvOutput = exporter.convertToCSV();
        const csvBlob = new Blob([csvOutput], {type: "text/csv" });
        const blobURL = URL.createObjectURL(csvBlob);

        const anchorElement = document.createElement("a");

        anchorElement.href = blobURL;
        // sets the name of the file the user will download
        anchorElement.download = "LEAT-data.csv";
        anchorElement.click();

        // reduces the amount of memory used by the browser
        setTimeout(() => {
            URL.revokeObjectURL(blobURL);
        }, 500);
    })

    // console.log(new TableCSVExporter(primaryInputByPerson).convertToCSV());



</script>

我已经到了可以控制台记录来自inputArrayselectArray 的每个元素的用户输入值的地步,尽管我似乎不知道如何让parsedValue 保存价值观。我将tableCell 转换为一个数组,因为我读到NodeListsHTMLcollections 不提供与常规数组相同的功能。我实际上是在尝试使用 .value 来获取值,就像在大多数 DOM 场景中一样。

下载的 .csv 文件将显示 undefinednull 或 [object HTMLInputElement]/[object HTMLSelectElement],具体取决于我的 console.log()

这是我在网站上的第一个问题。我想我可能会打破一些(或很多)惯例,欢迎任何关于未来提出更好问题的反馈!

注意:我将所有功劳归功于 Domenic Corso 和他的视频 https://www.youtube.com/watch?v=cpHCv3gbPuk&t=713s,因为他们几乎提出了上述所有代码!

【问题讨论】:

  • 好吧..输入元素的id是person1所以..使用它。
  • 感谢@GottZ 的反馈!我尝试在 tableCell 上使用 .getElementById(),尽管它会抛出一个错误,说“getElementById 不是一个函数”......最重要的是,我没有在我的问题中提到我的应用程序有很多 和 元素,所以我需要在一次调用中获取所有这些元素。
  • 其次,您所说的.getElementById() 电话在哪里。我在您提供的代码中看不到它。不要假设人们会窃取您在此处发布的所有内容。 tbh 我是那种甚至可以用更简洁的代码重新实现你的想法的人。 ps:如果您遇到需要带有某种反作弊系统的表单的客户,请以此为灵感:gottz.de/visibility.htm
  • 哦,我没有省略它,因为我以为有人会偷。就像我在底部发帖一样,我不能将大部分代码归功于我,因为我正在关注另一个开发人员的教程。我意识到我把它换成我的编辑器中的代码来尝试它,发现它不起作用。我没有在这里反映。再次感谢您的反馈!

标签: javascript html csv dom nodelist


【解决方案1】:

尤里卡!

我终于破解了这把枪。这是做到这一点的那一行:

elementsArray.forEach(element =&gt; parsedValue.push(element.value));

我是因为这条线而来到这里的: elementsArray.forEach(element =&gt; console.log(element.value));

我发现我能够将我要输入到 &lt;input&gt;&lt;select&gt; 字段中的文本打印到控制台,所以经过大量的反复试验,我写了第一行来推送将所有内容放入一个新数组parsedValue = [],返回parsedValue,并让它成功写入CSV文件!

如果阅读本文的任何人想要进一步说明我在这个项目中究竟做了什么,我非常乐意提供!

【讨论】:

    猜你喜欢
    • 2019-04-03
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 2014-09-13
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多