以动态方式访问动态创建的变量

Accessing a dynamically created variable in a dynamic way

本文关键字:动态 变量 创建 访问 方式      更新时间:2023-09-26

这可能需要一些解释,所以请耐心等待。

我正在尝试创建 X 个表,每个表的

长度(列)Y 不同,每个表有 4 行,X 和 Y 由用户确定。这部分我已经解决了。

问题在于每个表中的每个单元格都必须包含自己的文本框,该文本框将包含从数据库派生的数字。如果用户更改了文本框中的数字,则更改必须反映在数据库中。

鉴于表的数量和表的长度未知,我无法提前设置文本框的名称,必须动态设置。

我遇到了这段代码:

var pageNumber = 1;
eval("var text" + pageNumber + "=123;");
alert(text1);
//alert shows '123'

我相信(经过修改)将允许我为每个文本框动态创建一个唯一的名称。我遇到的问题是,由于我不知道它叫什么(在创建表之后),我该如何访问这个新文本框?

我计划使用 3D 数组来保存我想在表中的每个单元格中显示的数字,并计划使用此数组来命名单元格。

例如,数组可以是 array[i][j][k],假设 i=1, j=2, k=3,它将包含数字 8。动态创建的文本框名称如下所示:文本框123

如何将数组(包含 8)中的该单元格与该新文本框相关联,然后在我提前不知道它的名称时检索并存储一个新值?

我的想法

,我怎么写这样的东西

 <input type="text" name="textBox123" value=array[i][j][k]> 

到网页?

再说一次,也许我想多了,有更好的方法。如果是这样,请告诉我。

HTML:

<div id="tables"></div>

JavaScript:

var tables = [
        // Table #1
        [
            [111, 112, 113], // Row #1
            [121, 122, 123]  // Row #2
        ],
        // Table #2
        [
            [211, 212, 213, 214], // Row #1
            [221, 222, 223, 224], // Row #2
            [231, 232, 233, 234]  // Row #3
        ],
        // Table #3 (empty!)
        []
    ],
    nr, nc, i, j, k,
    name, value, textBox, cell, row, table,
    $tables = $("#tables");
for (i = 0; i < tables.length; ++i) {
    nr = tables[i].length;
    nc = nr > 0 ? tables[i][0].length : 0;
    table = "<table>";
    for (j = 0; j < nr; ++j) {
        row = "<tr>";
        for (k = 0; k < nc; ++k) {
            name = "textBox" + (i + 1) + (j + 1) + (k + 1);
            value = tables[i][j][k];
            textBox = "<input type='text' name='" + name + "' value='" + value + "'>";
            cell = "<td>" + textBox + "</td>";
            row += cell;
        }
        row += "</tr>'n";
        table += row;
    }
    table += "</table>'n";
    $tables.append(table);
}

参见 jsfiddle。第三个空表将作为空table标签插入,但这不是必需的。

我想提一下,由于您需要将这些表连接到数据库,因此一个优雅的解决方案是使用客户端MVC框架,例如Backbone.js。在这里,您可以找到一本很好的介绍书。视图可以使用类似于上述代码的代码来render表。tables数组可以存储在集合中。

您不必使用索引预先标记表中的每个单元格,因为您可以根据需要根据 DOM 层次结构对其进行计算。

如果表中有一个任意单元格,则可以像这样获取表中该单元格的行号和列号,其中传递给此函数的cell可以是td对象或其任何后代(例如表中的<input>标记):

// Pass any td object or descendant of a td object in a <table> and it will return
// an object with {row: x, col: y}
// or return null if the cell passed wasn't inside a <tr> and <td>
function findRowColInTable(cell) {
    function findParent(obj, parentTagName) {
        parentTagName = parentTagName.toUpperCase();
        while (obj && obj.tagName != parentTagName) {
            obj = obj.parentNode;
        }
        return obj;
    }
    findChildCnt(obj) {
        var cnt = 0;
        while (obj = obj.prevSibling) {
            ++cnt;
        }
        return cnt;
    }
    var td, tr, col, row;
    // get table cell
    td = findParent(cell, "TD");
    if (td) {
        col = findChildCnt(td);
        tr = findParent(td, "TR");
        if (tr) {
            row = findChildCnt(tr);
            return {row: row, col: col};
        }
    }
    return null;
}

仅供参考,这在jQuery中要容易得多,您可以使用.closest(tag).index()来找到合适的父母并获取本地兄弟姐妹的数量,但是我为您提供了一个纯JavaScript版本。

您实际上可以在表单上执行数组。以我的旧答案为例,您可以使用这种命名方案在表单输入中创建数组。在后端,你把它们作为数组(假设PHP)。

如果你通过JS获取值,你可以基于这个答案,它利用命名方案,获取表单值并将它们转换为JS对象和数组,类似于PHP在后端接收它们的方式。基本上,它贯穿表单并获取表单值。它部分是jQuery,但是如果你不想合并整个库,你可以从jQuery获取源代码。

你可以利用javascript面向对象的概念

每个表都有其对应的表对象,其行和单元格也是如此。使用这种技术,每个对象在真正的DOM中都有其"元素"。

诀窍是,将事件侦听器

(例如,当用户在文本框中键入某些内容时)附加到对象,以便该事件侦听器仅对应于该特定单元格,而不会弄乱其他列、行和表中的其他单元格。

这是可能的解决方案。对不起,我的jQuery严重依赖。我只是不确定如何使用document.createElement()(我的糟糕知识)创建元素,您当然可以使用纯javascript实现(没有jQuery)更改它们。

     values=new Array();
     function Cell(id,values_row){ //Cell class
        this.id=id;
        this.element=$("<td></td>");           
        this.textbox=$("<input type='text' name='"+this.id+"' id='"+this.id+"'></input>");
        values_row[id]="" //initiate default value == ""
            //here is the trick
        this.textbox.change(function(){ //you can use onchange if you dont like jQuery
            values_row[id]=$(this).val();             
            //other tasks need to be done when user changes the value of a textbox (typing)
        });
        this.textbox.appendTo(this.element);    
    }
    function Row(id,number_of_columns,values_table){ //Row class
        this.id=id
        this.element=$("<tr></tr>")                
        values_table[id]=new Array(); //make array "values" becomes 3D              
        for(var col =0;col<number_of_columns;col++){
            var the_cell=new Cell(col,values_table[col]);
            the_cell.element.appendTo(this.element);
        }
    }
    function Table(id,number_of_columns){ //Table class
        this.id=id
        this.element=$("<table></table>")
        values[id]=new Array();  //make array "values" becomes 2D                     
        for(var row=0;row<4;row++){
            var the_row=new Row(row,number_of_columns,values[id]);
            the_row.element.appendTo(this.element)                       
        }
    }
    // creating the tables
    for(var t=0;t<number_of_tables_needed;t++){
        the_table=new Table(t,number_of_column_for_this_table);
        the_table.element.appendTo(table_container_element);
    }
    //do input some text into some cells then
    alert(values)

警报将显示一个 3D 数组,其中包含按表号、行号索引的所有单元格的值,当然还有精确指向单元格的列。单元格值的默认值为 "

使用此技术,您无需为刚刚输入值的相应单元格找到正确的数组元素。相反,请在 DOM 中创建元素之前附加事件侦听器。这是一种面向对象的方式/解决问题的方法。

当您每次输入时都需要查找相应的数组单元时,而不是具有 O(n^3) 算法的复杂性,此解决方案在对象初始化期间花费更多时间,但之后,它是 O(1)。