Array.from() 没有将 nodeList 转换为数组

Array.from() not converting nodeList into an array

我使用 createElement() 创建了一个列表元素的 nodeList。然后我使用 Array.from() 将有问题的 nodeList 转换为我可以迭代的数组。我想根据索引值应用不同的宽度。如果索引的宽度为 300px,否则宽度为 500px。但是,控制台 returns“无法读取 bottlesOnTheWall 处未定义的 属性 'style'”。

我还使用 [...] 将我的 nodeList 转换为数组,但也没有成功。我的猜测是,它首先不是 nodeList,这意味着它不能转换为数组。至少不使用这两种方法中的任何一种。

我想知道是否有人可以指出我哪里出错并修复我的代码。我一直在花更多的时间来尝试这样做。

const bottles = document.getElementById("bottles");
count = 99;
var myArray = [];
var j = 0;

function bottlesOnTheWall() {
  while (count > 0) {
    if(count > 2) {
      myArray.push(`${count} bottles of beer on the wall, ${count} bottles of beers. Take one down and pass it around, ${count - 1} bottles of beer on the wall`)
    } else if (count === 2) {
      myArray.push(`${count} bottles of beer on the wall, ${count} bottles of beers. Take one down and pass it around, ${count - 1}bottle of beer on the wall`)
    } else if (count === 1) {
      myArray.push(`${count} bottle of beer on the wall, ${count} bottles of beers. No more bottle of beer on the wall`)
    } else {
      myArray.push(`No more bottles of beer on the wall. No more bottles of beer.  Go to the shop and buy some ${count} more.`)
    }
    count--
  }
  while (j < myArray.length) {
    var liElement = document.createElement("li");
    var text = document.createTextNode(myArray[j]);
    liElement.appendChild(text);
    bottles.appendChild(liElement);
    var bottlesArray = Array.from(bottles);
    if(j % 2) {
      bottlesArray[j].style.width = "300px";
    } else {
      bottlesArray[j].style.width = "500px";
    }
    j++;
  }
}
bottlesOnTheWall();
#bottles {
  line-height: 2;
  letter-spacing: 3px;
}

/* ul {
  list-style-image: url('beer.png');
} */

body {
  background: #FFF8DC;
}

li {
  max-width: 500px;
  margin: auto;
  margin-bottom: 10px;
}

ul li {
  background: #FFEBCD;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>bottles on the wall</title>
    <link rel="stylesheet" href="index.css">
  </head>
  <body>
    <ul id="bottles" ></ul>
    <script src="index.js" type="text/javascript"></script>

  </body>
</html>

Array.from needs a variable with an implemented Symbol.iterator。单个元素没有,是元素列表,这里就不给了。

那你还有一些问题:

  • 全局变量,但只在单个函数中使用。只需将所有变量移动到函数内部即可。

  • 取参数为count.

  • 在不先将所有文本收集到数组中的情况下进行一次循环,然后再次迭代以创建元素。唯一的目的是使用层模型将数据收集与表示层分开。

  • 最后拿一个conditional (ternary) operator ?: for width.

function bottlesOnTheWall(count) {
    const bottles = document.getElementById("bottles");
    
    while (count > 0) {
        let text;

        if (count > 2) text = `${count} bottles of beer on the wall, ${count} bottles of beers. Take one down and pass it around, ${count - 1} bottles of beer on the wall`;
        else if (count === 2) text = `${count} bottles of beer on the wall, ${count} bottles of beers. Take one down and pass it around, ${count - 1} bottle of beer on the wall`;
        else if (count === 1) text = `${count} bottle of beer on the wall, ${count} bottles of beers. No more bottle of beer on the wall`;
        else text = `No more bottles of beer on the wall. No more bottles of beer.  Go to the shop and buy some ${count} more.`;

        count--;

        const liElement = document.createElement("li");
        liElement.appendChild(document.createTextNode(text));
        bottles.appendChild(liElement);
        liElement.style.width = count % 2
            ? "300px"
            : "500px";
    }
}

bottlesOnTheWall(99);
#bottles { line-height: 2; letter-spacing: 3px; }
body { background: #FFF8DC; }
li { max-width: 500px; margin: auto; margin-bottom: 10px; }
ul li { background: #FFEBCD; }
<ul id="bottles"></ul>

您可以进一步推动 DRY 原则并通过这样做缩短脚本。 <li> 的交替宽度可以通过使用一个简单的 CSS 选择器来强制执行:li:nth-child(even) { max-width:300px }.

函数 bob(n) 生成一个字符串,指定啤酒瓶数,并在 bottlesOnTheWall() 函数中定义。然后它可以在任何地方使用,并将提供一个适当变形的字符串,其中包含任意数量的 n.

function bottlesOnTheWall(count) {
  let n=count;
  const LIs=[],
        bob=n=>(n>1?n:(n==0?'no more':1))+' bottle'+(n==1?'':'s')+' of beer';       
  do {
    LIs.push('<li>'+bob(n)[0].toUpperCase()+bob(n).substring(1)+' on the wall, '
    +bob(n)+'. '
    +(n?`Take one down and pass it around, ${bob(n-1)} on the wall`
       :`No more bottles of beer.  Go to the shop and buy some ${count} more.`)
    +'</li>'
    );
  } while(n--)
  document.getElementById("bottles").innerHTML=LIs.join('\n')    
}

bottlesOnTheWall(9);
#bottles { line-height: 2; letter-spacing: 3px; }
body { background: #FFF8DC; }
li { max-width:500px; margin: auto; margin-bottom: 10px; }
li:nth-child(even) { max-width:300px }
ul li { background: #FFEBCD; }
<ul id="bottles"></ul>