而Loop:生成的表行和列不一致

时间:2015-11-10 15:22:21

标签: javascript jquery html loops html-table

请解释为什么我从另一个SO问题中借用的代码会产生不一致的结果。该程序接受2个输入,行和列。它应该然后生成一个表,其中包含输入的表行和表列的确切数量。但是,第一行似乎将单元格相乘并减少每一行,直到最后一行实际呈现每一行应该是什么。

另外,我注意到当我在内部while循环内移动第25行时,会生成一个类似金字塔的表(这很酷),但我无法解释它在做什么。 / p>

$("<tr class='tableRow'>").appendTo('table#container');

所以说,请帮我生成一个表,当输入相等时,该表将均匀地呈现行和列。

注意:为行输入1,为列输入1确实会返回预期的结果,但这是它&#34;工作的唯一情况&#34;。输入2表示行,2表示列,会产生意外结果。

Sandbox Fiddle

&#13;
&#13;
//Table Generator
var c = 10; //parseInt(prompt("Enter column "), 10);
var r = 10; //parseInt(prompt("Enter row "), 10);
var cTmp = c;
var rTmp = r;

function rowLoop() {
  $('tr.tableRow').each(function(index) {
    var trFound = $("tr.tableRow:eq(" + index + ")");
    var rowNum = parseInt(($("tr.tableRow:eq(" + index + ")").index()), 10);
    var tdAdd = "<td>test</td>";
    if ($(this).index() === rowNum) {
      trFound.append(tdAdd);
      console.log("Add a TD");
      console.log(rowNum + "=" + $(this).index());
      console.log(rowNum + "=" + $(this).index());
    } else {
      console.log(rowNum + "<>" + $(this).index());
      console.log(rowNum + "<>" + $(this).index());
    }
  });
}
while (0 < rTmp) {
  cTmp = c;
  $("<tr  class='tableRow'>").appendTo('table#container');
  while (0 < cTmp) {
    rowLoop();
    cTmp--;
  }
  document.getElementById("container").innerHTML = document.getElementById("container").innerHTML + "</tr>";
  rTmp--;
}
&#13;
table {
  border-collapse: collapse;
  border: solid 1px #ACE;
}
tr {
  height: 15px;
}
td {
  border: solid 1px red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table id='container'></table>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:3)

而不是使用while-loop为什么不使用简单的嵌套 for-loop?这将使这项任务更容易阅读和理解。

//Table Generator
var cols = 10; //parseInt(prompt("Enter column "), 10);
var rows = 10; //parseInt(prompt("Enter row "), 10);

generateTable('container', rows, cols, 'test');

function generateTable(id, rows, cols, fill) {
  var elTable = document.getElementById(id);
  createRows(elTable, rows, cols, fill);
}

function createRows(elTable, rows, cols, fill) {
  for (var row = 0; row < rows; row++) {    
    elTable.appendChild(createRow(row, cols, fill));
  }
}

function createRow(row, cols, fill) {
  var elRow = document.createElement('tr');
  elRow.className = 'tableRow';
  createCols(elRow, row, cols, fill);
  return elRow;
}

function createCols(elRow, row, cols, fill) {
  for (var col = 0; col < cols; col++) {
    elRow.appendChild(createCol(row, col, fill));
  }
}

function createCol(row, col, fill) {
  var elCol = document.createElement('td');
  elCol.innerHTML = fill || row + 'x' + col;
  return elCol;
}
table {
  border-collapse: collapse;
  border: solid 1px #ACE;
}
tr {
  height: 15px;
}
td {
  border: solid 1px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='container'></table>

答案 1 :(得分:1)

jQuery插件

您可以完全跳过循环并使用范围映射。您可以使用以下方法实际定义数组:

Array.apply(null, Array(n)) // Where n is an integer greater than 0

然后,您可以将数组中的每个项目映射到地图函数中的函数或当前索引。

map(function(_, idx) {
    // Return the current index in the map's "loop" callback.
    if (val == null) return idx;
    // Execute the value as a function; pass index as 1st param.
    if (isFunction(val)) return val.call(null, idx);
    // Return the value as an (assumed) scalar value.
    return val;
});

这是一个jQuery插件,使用上面解释的技巧生成行和列,以使用选项默认值生成所需大小的数组。

//Table Generator
(function($) {
  $.fn.generateTable = function(options) {
    var defaults = {
      rows: 0,
      cols: 0,
      fill: function(row, col) {
        return row + 'x' + col;
      }
    };
    var opts = $.extend(defaults, options);
    function fillArray(n, val) {
      return Array.apply(null, Array(n)).map(function(_, idx) {
        return val == null ? idx : isFunction(val) ? val.call(null, idx) : val;
      });
    }
    function isFunction(value) {
      return typeof value == 'function';
    }
    return $(this).append(fillArray(opts.rows, function(row) {
      return $('<tr>', {
        class: 'tableRow'
      }).append(fillArray(opts.cols, function(col) {
        return $('<td>', {
          text: isFunction(opts.fill) ? opts.fill.call(null, row, col) : opts.fill
        });
      }));
    }));
  };
}(jQuery));

$(function() {
  $('#container').generateTable({
    rows: 10, //parseInt(prompt("Enter row count"), 10)
    cols: 10, //parseInt(prompt("Enter column count"), 10)
    fill: 'test'
  });
});
table {
  border-collapse: collapse;
  border: solid 1px #ACE;
}
tr {
  height: 15px;
}
td {
  border: solid 1px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='container'></table>

发展阶段

下面,您将看到每个连续的代码块是如何从其前身发展而来的。

予。 Vanilla JavaScript转换为jQuery

//Table Generator
var cols = 10; //parseInt(prompt("Enter column "), 10);
var rows = 10; //parseInt(prompt("Enter row "), 10);

generateTable('#container', rows, cols, 'test');

function generateTable(selector, rows, cols, fill) {
  var $el = $(selector)
  createRows($el, rows, cols, fill);
}

function createRows($table, rows, cols, fill) {
  for (var row = 0; row < rows; row++) {
    $table.append(createRow(row, cols, fill));
  }
}

function createRow(row, cols, fill) {
  var $row = $('<tr>', {
    class: 'tableRow'
  });

  createCols($row, row, cols, fill);

  return $row;
}

function createCols($row, row, cols, fill) {
  for (var col = 0; col < cols; col++) {
    $row.append(createCol(row, col, fill));
  }
}

function createCol(row, col, fill) {
  return $('<td>', {
    text: fill || row + 'x' + col
  });
}
table {
  border-collapse: collapse;
  border: solid 1px #ACE;
}
tr {
  height: 15px;
}
td {
  border: solid 1px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='container'></table>

II。简单的jQuery插件

//Table Generator
(function($) {
  $.fn.generateTable = function(options) {
    var $table = $(this);
    _createRows($table, options.rows, options.cols, options.fill);
  };
  _createRows = function($table, rows, cols, fill) {
    for (var row = 0; row < rows; row++) {
      $table.append(_createRow(row, cols, fill));
    }
  };
  _createRow = function(row, cols, fill) {
    var $row = $('<tr>', {
      class: 'tableRow'
    });

    _createCols($row, row, cols, fill);

    return $row;
  };
  _createCols = function($row, row, cols, fill) {
    for (var col = 0; col < cols; col++) {
      $row.append(_createCol(row, col, fill));
    }
  };
  _createCol = function(row, col, fill) {
    return $('<td>', {
      text: fill || row + 'x' + col
    });
  };
}(jQuery));

var cols = 10; //parseInt(prompt("Enter column "), 10);
var rows = 10; //parseInt(prompt("Enter row "), 10);

$(function() {
  $('#container').generateTable({
    rows: rows,
    cols: cols,
    fill: 'test'
  });
});
table {
  border-collapse: collapse;
  border: solid 1px #ACE;
}
tr {
  height: 15px;
}
td {
  border: solid 1px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='container'></table>

III。高级jQuery插件

//Table Generator
(function($) {
  $.fn.generateTable = function(options) {
    $(this).append(_fillArray(options.rows, function(row) {
      return $('<tr>', {
        class: 'tableRow'
      }).append(_fillArray(options.cols, function(col) {
        return $('<td>', {
          text: options.fill || row + 'x' + col
        });
      }));
    }));
  };

  function _fillArray(n, defaultValue) {
    return Array.apply(null, Array(n)).map(function(val, idx) {
      if (defaultValue === undefined) return idx;
      if (typeof defaultValue == 'function') return defaultValue.call(null, idx);
      return defaultValue;
    });
  }
}(jQuery));

var colCount = 10; //parseInt(prompt("Enter column "), 10);
var rowCount = 10; //parseInt(prompt("Enter row "), 10);

$(function() {
  $('#container').generateTable({
    rows: rowCount,
    cols: colCount,
    fill: 'test'
  });
});
table {
  border-collapse: collapse;
  border: solid 1px #ACE;
}
tr {
  height: 15px;
}
td {
  border: solid 1px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='container'></table>

答案 2 :(得分:0)

您的问题很可能源于这样一个事实:在每个rowLoop()执行中,您使用它作为迭代的选择器:

$('tr.tableRow')

这将获取当前在DOM中进行迭代的所有行,而不仅仅是当前正在处理的行。

一些选择:

  • 首先构建一个包含X个列的单行对象,然后对其进行克隆并附加到表中以获取Y行数。
  • 首先构建Y空TR,然后迭代每个TR,附加X TD&#39>。