HTML + JS-尝试用div包围通过for循环创建的某些内容

时间:2018-07-31 19:31:23

标签: javascript html

我正在编写冒险游戏,并且具有原始的sortInventory()功能。它在player.inventory数组中循环,并以自己的<div>显示每个项目。我想用<div class="inv">包围整个完成的“清单”-以下是功能:

function sortInventory() {
  var rowCount = 0;
  var firstRowDone = false;

  for(var i = 0; i < player.inventory.length; i++) {
    rowCount++;
    if(rowCount == 6 && firstRowDone == false) {
      firstRowDone = true;
      rowCount = 0;
      dock.innerHTML += "<br>"
    }
    if(rowCount == 5 && firstRowDone) {
      dock.innerHTML += "<br>"
      rowCount = 0;
    }
    dock.innerHTML += "<div class='inv-item'><img class='inv-img' src='" + player.inventory[i].img + "'></img></div>";
  }
}

function showInventory() {
  dock.innerHTML = "<div class='inv'>";
  sortInventory();
  dock.innerHTML += "</div>"
}

当前输出:

<div class="inv"></div>
<div class="inv-item">..</div>
<div class="inv-item">..</div>
<!-- and so on -->

但是我希望它输出:

<div class="inv">
    <div class="inv-item">..</div>
    <div class="inv-item">..</div>
    <!-- and so on -->
</div>

我如何才能实现这一目标,为什么它会提前关闭标签?提前致谢。

6 个答案:

答案 0 :(得分:3)

与其将其分块编写,不如将其存储在变量中并一次全部编写。

function sortInventory() {
  var rowCount = 0;
  var invList = '';

  for(var i = 0; i < player.inventory.length; i++) {
    rowCount++;
    if(rowCount == 6 && firstRowDone == false) {
      firstRowDone = true;
      rowCount = 0;
      dock.innerHTML += "<br>"
    }
    if(rowCount == 5 && firstRowDone) {
      dock.innerHTML += "<br>"
      rowCount = 0;
    }
    invList += "<div class='inv-item'><img class='inv-img' src='" + player.inventory[i].img + "'></img></div>";
  }
  return invList;
}

function showInventory() {
  dock.innerHTML = "<div class='inv'>" + sortInventory() + "</div>";      
}

之所以发生这种情况,是因为没有关闭标签的情况下,打开标签不能存在于DOM内,只有极少数例外,例如<br />仍有效为<br >,因此大多数浏览器都会尝试对此进行补偿。为您编写关闭标签。

简而言之,以增量方式写入innerHTML标记始终是一个坏主意,并且会导致意外结果,因为大多数所有浏览器都会尝试对其进行纠正。

答案 1 :(得分:3)

使用innerHTML可能很麻烦,更不用说(有时)很危险了。相反,我将使用document.createElementNode.appendChild方法。

function sortInventory() {
  var rowCount = 0;

  var inv = document.createElement('div');
  inv.classList.add('inv');

  for(var i = 0; i < player.inventory.length; i++) {
    rowCount++;
    if(rowCount == 6 && firstRowDone == false) {
      firstRowDone = true;
      rowCount = 0;
      inv.appendChild(document.createElement('br'));
    }
    if(rowCount == 5 && firstRowDone) {
      inv.appendChild(document.createElement('br'));
      rowCount = 0;
    }
    var invItem = document.createElement('div');
    invItem.classList.add('inv-item');

    var invImg = document.createElement('img');
    invImg.classList.add('inv-img');
    invImg.setAttribute('src', player.inventory[i].img);

    invItem.appendChild(invImg);
    inv.appendChild(invItem);
  }

  dock.appendChild(inv);
}

function showInventory() {
  sortInventory();
}

答案 2 :(得分:2)

我认为它过早关闭了标签,因为.innerHTML接收到的值会删除元素的所有后代,并通过解析字符串中给定的HTML将其替换为构造的节点。对于构造的节点,这意味着(在这种情况下)如果有任何未关闭的标记,它将首先将其关闭(因此它是一个构造的节点)。

因此,为了解决这个问题,首先构建字符串,最后使用innerHTML来设置构建值。

按照您的逻辑,将是这样的:

var newHtml = "";
function sortInventory() {
  var rowCount = 0;

  for(var i = 0; i < player.inventory.length; i++) {
    rowCount++;
    if(rowCount == 6 && firstRowDone == false) {
      firstRowDone = true;
      rowCount = 0;
      newHtml += "<br>"
    }
    if(rowCount == 5 && firstRowDone) {
      newHtml += "<br>"
      rowCount = 0;
    }
    newHtml += "<div class='inv-item'><img class='inv-img' src='" + player.inventory[i].img + "'></img></div>";
  }
}

function showInventory() {
  newHtml = "<div class='inv'>";
  sortInventory();
  newHtml += "</div>"
  dock.innerHTML = newHtml;
}

答案 3 :(得分:1)

为了在带有.inv类的元素周围创建带有.inv-item类的包装元素,请在sortInventory函数的字符串处构造HTML内容,然后以{返回设置content元素的dock时要使用的{1}}:

innerHTML
var boxIcon = 'https://image.flaticon.com/icons/svg/122/122186.svg';
var player = {
  inventory: [
    {img: boxIcon},
    {img: boxIcon},
    {img: boxIcon}
  ]
};
var dock = document.getElementById('dock');

function sortInventory(inv) {
  var rowCount = 0;
  var content = ''

  for (var i = 0; i < player.inventory.length; i++) {
    rowCount++;
    if (rowCount == 6 && firstRowDone == false) {
      firstRowDone = true;
      rowCount = 0;
      content += "<br>"
    }
    if (rowCount == 5 && firstRowDone) {
      content += "<br>"
      rowCount = 0;
    }
    content += "<div class='inv-item'><img class='inv-img' width='32px' src='" + player.inventory[i].img + "'></img></div>";
  }
  
  return content;
}

function showInventory() {
  dock.innerHTML = "<div class='inv'>" + sortInventory() + "</div>";
}

showInventory();
.inv {
  background: #CCC;
}

Credits to Flaticon

答案 4 :(得分:0)

完全构造HTML字符串,然后分配给innerHTML的{​​{1}},而不是分配div 3次。

更改innerHTML函数以返回字符串,附加所有字符串并将其立即分配为sortInventory

答案 5 :(得分:0)

您可以先使用“ inv”类创建该项目,然后使用document.getElementByClassName("inv")通过类名获取该项目,然后使用forloop document.getElementByClassName("inv").innerHtml += <div class="inv-item">..<div>

添加