为什么我不能让我的图像出现在表格单元/节点中...也许我可以得到一些关闭?

时间:2015-01-13 13:00:33

标签: javascript image loops closures

我想在新表的每个单元格中添加一个新图像,并为其提供与旧表相同的源,然后使其可单击。首先,我这样做了:

function showData() {
  if (localStorage.getItem(name) !== null) {
    var showme = localStorage.getItem(name);
    alert("I got the table");
    var newTable = document.createElement('table');
    newTable.innerHTML = showme;
    newTable.id = "newTable";

    newNumRows = newTable.getElementsByTagName('tr').length;
    newNumCells = newTable.getElementsByTagName('td').length;
    newNumCols = newNumCells / newNumRows;
    alert(newNumRows);
    alert(newNumCells);
    alert(newNumCols);

    var newImages = newTable.getElementsByTagName('img');
    for (var i = 0; i < newImages.length; i += 1) {
      var picSource = newImages[i]['src'];
      console.log(picSource);
    }

    function addNewImage(newNumCols) {
      var newImg = new Image();
      newImg.src = picSource;
      col.appendChild(newImg);
      newImg.onclick = function() {
        alert("WOW");
      };
    }

    for (r = 0; r < newNumRows; r++) {
      row = newTable.insertRow(-1);

      for (c = 0; c < newNumCols; c++) {
        col = row.insertCell(-1);
        addNewImage(newNumCols);
      }
    }

    var showIt = document.getElementById('holdTable');
    showIt.appendChild(newTable);
  }
}

这在一定程度上起作用,但不幸的是,只显示了最后一张图像。所以,我做了一些环顾四周,我认为这与封闭有关(对任何重复道歉),但这是一个我真正难以理解的概念。所以我试过这个:

function showData() {
  if (localStorage.getItem(name) !== null) {
    hideTaskForm();
    var showme = localStorage.getItem(name);
    var oldTable = document.createElement('table');
    oldTable.innerHTML = showme;
    newTable = document.createElement('table');
    newTable.id = "newTable";
    var i, r, c, j;

    newNumRows = oldTable.getElementsByTagName('tr').length;
    newNumCells = oldTable.getElementsByTagName('td').length;
    newNumCols = newNumCells / newNumRows;
    var newTableCells = newTable.getElementsByTagName('td');
    var getImages = oldTable.getElementsByTagName('img');

    for (r = 0; r < newNumRows; r++) {
      row = newTable.insertRow(-1);

      for (c = 0; c < newNumCols; c++) {
        makeNodes = row.insertCell(-1);
      }
    }

    for (var j = 0; j < newTableCells.length; j++) {
      var theNodeImage = document.createElement("img");
      newTableCells[j].appendChild(theNodeImage);
      alert(newTableCells[j].innerHTML); //This gives me img tags
    }

    for (i = 0; i < getImages.length; i += 1) {
      var oldSource = getImages[i]['src']; //gets the src of the images from the saved table
      console.log(oldSource);
      //alert(oldSource);//successfully alerts the image paths
      var newPic = new Image(); //creates a new image

      (function(newPic, oldSource) {
        newPic.src = oldSource;
        alert(newPic.src); //gives the same image paths
        newTable.getElementsByTagName('img').src = newPic.src; //This doesn't work - table is blank???
      })(newPic, oldSource);
    }

    var showIt = document.getElementById('holdTable');
    showIt.appendChild(newTable);
  }
}

现在,这不会引发任何错误。但是,它也没有填满。它确实给了我源代码,我想我已经创建了新的图像对象来附加到newTableCells中的img标签,但是表格显示为空白。我不知道我哪里出错了。所有的帮助真的很受欢迎。

注意:即使作为业余爱好者,即使我知道可能有更多有效的方法可以做到这一点,但我故意这样做,试图帮助我理解我正在采取的每个步骤的逻辑。

1 个答案:

答案 0 :(得分:1)

在您的代码中,您有:

var newImages = newTable.getElementsByTagName('img');

for (var i = 0; i < newImages.length; i += 1) {
  var picSource = newImages[i]['src'];
  console.log(picSource);
}

最后, picSource 具有最后一个图像的 src 属性的值。然后是:

function addNewImage(newNumCols) {
  var newImg = new Image();
  newImg.src = picSource;
  col.appendChild(newImg);
  newImg.onclick = function() {
    alert("WOW");
  };
}

值传递给 newNumCols 但未在函数中使用。 picSource 的值来自外部执行上下文,并且不会更改,因此它仍然是前一个for循环的最后一个图像src。

for (r = 0; r < newNumRows; r++) {
  row = newTable.insertRow(-1);

  for (c = 0; c < newNumCols; c++) {
    col = row.insertCell(-1);
    addNewImage(newNumCols);
  }
}

此循环只是使用函数中未使用的单个参数调用 addNewImage ,因此您可以一遍又一遍地获得相同的图像。

对于记录, addNewImage 函数确实有 picSource 的闭包,但它也有一个闭包到外部执行上下文的所有变量。这不是问题,虽然它可能掩盖了你没有在每次调用中为 picSource 设置值的事实,所以你从上一段代码中获得了剩余值。

您尚未提供 showme 内容的任何指示,因此无法确定此方法是否可行。

注意

你在哪里:

var showme = localStorage.getItem(name);
alert("I got the table");
var newTable = document.createElement('table');
newTable.innerHTML = showme;
newTable.id = "newTable";

IE不支持设置表元素的innerHTML属性,但您可以创建整个表作为其他元素的innerHTML并设置单元格的innerHTML(tr,th)。如果您想使用这种方法,请考虑:

var div = document.createElement('div');
div.innerHTML = '<table id="newTable">' + showme + '<\/table>';
var newTable = div.firstChild;