【问题标题】:For loop runs length of array but displays one element array.length timesFor 循环运行数组的长度,但显示一个元素 array.length 次
【发布时间】:2017-02-19 07:11:58
【问题描述】:

我正在为 freeCodeCamp 开发一个项目,并且正在通过一组 twitch.tv 用户运行 for 循环。我创建了一个表,对于数组中的每个用户名,它应该添加新行,用数据填充它,然后移动到下一个元素。问题是每次我运行代码时,它似乎都是在数组中选择一个随机索引并运行循环以等于数组中的元素数。我认为这是一个显示问题,因为它为每个单独的呼叫连接到服务器。

希望有人能帮帮我。

var twitch = ['ESL_SC2', 'OgamingSC2', 'cretetion', 'freecodecamp', 'storbeck', 'habathcx', 'RobotCaleb', 'noobs2ninjas', 'ESL_LOL', 'wow_2', 'brunofin', 'comster404']

var streams = 'https://wind-bow.gomix.me/twitch-api/streams/';
var channels = 'https://wind-bow.gomix.me/twitch-api/channels/';
var users = 'https://wind-bow.gomix.me/twitch-api/users/';


var getStream = function(data) {

  if (data.stream === null) {
    $('.status').append('Offline');
  } else {
    var streamStatus = data.stream.channel.status;
    var html = '<td class="stream">' + streamStatus + '</td>';
    $('.stream').html(html);
  }

}
var getChannels = function(data) {
  var game = data.display_name;

  var logoHtml = data.logo;
  var channelUrl = data.url;
  var gameHtml = '<a href=' + channelUrl + ' target="_blank">' + game + '</a>';
  var logoHtml = '<img class="image" src="' + logoHtml + '">';
 
  $('.game').html(gameHtml);
  $('.logo').html(logoHtml);

}


$(document).ready(function() {

  $('.choice').on('click', function() {
    $('.choice').removeClass('selected');
    $(this).toggleClass('selected');
  });

  var table = $('<table id="twitch-table"></table>').appendTo('#content');

  for (var i = 0; i < twitch.length; i++) {
    var row = $('<tr></tr>').appendTo(table);
    $('<td class="logo"></td>').appendTo(row);
    $('<td class="game"></td>').appendTo(row);
    $('<td class="stream"></td>').appendTo(row);

    $.getJSON(streams + twitch[i], getStream, 'jsonp');
    $.getJSON(channels + twitch[i], getChannels, 'jsonp');



  }

});
body {
  padding: 0;
  margin: 0;
  font-family: 'Oswald', sans-serif;
  font-size: 100%;
}

a {
  text-decoration: none;
}

#main {
  width: 600px;
  margin: 2% auto 0;
}

#header {
  padding: 0;
  margin: 0;
  background: #116466;
  color: #d1e8e2;
  line-height: 100px;
  width: 100%;
}

h1 {
  margin: 0 0 0 5%;
  font-size: 300%;
}

#row {
  background: #285277;
  width: 100%;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  justify-content: space-between;
}

.choice {
  position: relative;
  text-align: center;
  width: 33%;
  background: #285277;
  padding: 5px 10px;
  display: inline-block;
  color: #d1e8e2;
  font-size: 150%;
}

.choice a {
  /*padding: 5px 20px;*/
  color: #d1e8e2;
}

#content {
  width: 100%;
  background: #efefef;
}


/*
.choice a:active {
	background: #1E3D59;
}
*/

.selected {
  background: #1E3D59;
}

.selected:after {
  content: '';
  position: absolute;
  top: 100%;
  right: 45%;
  width: 0;
  height: 0;
  border-top: solid 10px #1E3D59;
  border-left: solid 10px transparent;
  border-right: solid 10px transparent;
}

table {
  width: 600px;
}

tr {
  margin: 5px 0;
  display: flex;
  width: 100%;
  justify-content: space-between;
}

td {
  border-collapse: collapse;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
}

.game {
  padding-left: 10px;
  width: 100px;
  font-size: 120%;
  line-height: 75px;
  text-overflow: ellipsis;
}

.game a {
  color: #111;
}

.image {
  height: 75px;
  width: 75px;
}

.logo {
  padding: 3px 5px;
  box-sizing: border-box;
}

.stream {
  padding-right: 10px;
  width: 350px;
  display: inline-block;
  text-overflow: ellipsis;
  line-height: 75px;
}
<!DOCTYPE html>

<html>

<head>
  <title>Twitch.tv JSON API</title>
  <link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
  <script src="https://use.fontawesome.com/57c9bf8971.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>

<body>
  <div id='main'>
    <header id='header'>
      <h1>Twitch Streamers</h1>
    </header>
    <div id='row'>
      <ul>
        <li class='choice selected'><a href='#'>All</a></li>
        <li class='choice'><a href='#'>Online</a></li>
        <li class='choice'><a href='#'>Offline</a></li>
      </ul>
    </div>
    <div id='content'>

    </div>
  </div>
</body>

</html>

【问题讨论】:

  • row 在我的 for 循环中声明;第一行
  • 它只在for循环中声明

标签: javascript arrays json for-loop


【解决方案1】:

问题出在以下几行:

$('.game').html(gameHtml);
$('.logo').html(logoHtml);
$('.stream').html(html);

他们选择所有具有game 类(或logostream)的行并全部更改。

请参阅here 一个固定的 JSfiddle。

【讨论】:

  • 这正是我所需要的。谢谢你。我仍然存在的唯一问题是数组中的第一个元素没有出现。你有解决办法吗?
【解决方案2】:

您需要正确使用回调函数。您的 getStreamsgetChannels 函数将数据应用到所有行,而不是它自己的单个行。

以下是修改后的回调函数声明:

var getStream = function(url, idx) {
    $.getJSON(url, function(data){
        if (data.stream === null) {
            $('.status').append('Offline');
        } else {
            var streamStatus = data.stream.channel.status;
            var html = '<td class="stream">' + streamStatus + '</td>';
            $('tr').eq(idx).find('.stream').html(html);
        }
    });
}

var getChannels = function(url, idx) {
    $.getJSON(url, function(data){
        var game = data.display_name;
        var logoHtml = data.logo;
        var channelUrl = data.url;
        var gameHtml = '<a href=' + channelUrl + ' target="_blank">' + game + '</a>';
        var logoHtml = '<img class="image" src="' + logoHtml + '">';

        $('tr').eq(idx).find('.game').html(gameHtml);
        $('tr').eq(idx).find('.logo').html(logoHtml);
    });
}

并且,在您的 for 循环中将它们称为:

getStream(streams + twitch[i], i);
getChannels(channels + twitch[i], i);

JSFiddle 供您参考:https://jsfiddle.net/yogesh214/yxLu9mwg/4/

【讨论】:

    【解决方案3】:

    我现在明白你的问题了:

    正如@Shalom Peles 所说,您正在使用$('.stream') 选择所有文档中具有.stream 类的元素,而不仅仅是行中的元素。

    改为使用.find 在元素内进行选择。例如:

    let row = $('<div class="my-row"></div>'); // creates a row
    row.append(/* ... */);
    let elementInsideRow = row.find('.my-column'); // this selects an element *inside* the row element.
    

    另外:use let instead of var 用于所有声明


    我编辑了您的代码以适用于流。对频道做同样的事情。阅读 cmets。

    var twitch = ['ESL_SC2', 'OgamingSC2', 'cretetion', 'freecodecamp', 'storbeck', 'habathcx', 'RobotCaleb', 'noobs2ninjas', 'ESL_LOL', 'wow_2', 'brunofin', 'comster404']
    
    var streams = 'https://wind-bow.gomix.me/twitch-api/streams/';
    var channels = 'https://wind-bow.gomix.me/twitch-api/channels/';
    var users = 'https://wind-bow.gomix.me/twitch-api/users/';
    
    // refactor this like I did below
    var getChannels = function(data) {
      var game = data.display_name;
    
      var logoHtml = data.logo;
      var channelUrl = data.url;
      var gameHtml = '<a href=' + channelUrl + ' target="_blank">' + game + '</a>';
      var logoHtml = '<img class="image" src="' + logoHtml + '">';
     
      $('.game').html(gameHtml);
      $('.logo').html(logoHtml);
    
    }
    
    
    $(document).ready(function() {
    
      $('.choice').on('click', function() {
        $('.choice').removeClass('selected');
        $(this).toggleClass('selected');
      });
    
      var table = $('<table id="twitch-table"></table>').appendTo('#content');
    
      // you need to use `let` here because you need block scope
      // in general, use `let` instead of `var` everywhere.
      // https://stackoverflow.com/questions/21906133/when-should-i-use-let-and-var
      for (let i = 0; i < twitch.length; i++) {
        let row = $('<tr></tr>');
        $.getJSON(streams + twitch[i], function(data) {
            
            $('<td class="logo"></td>').appendTo(row);
            $('<td class="game"></td>').appendTo(row);
            $('<td class="stream"></td>').appendTo(row);
            if (data.stream === null) {
                // instead of selecting all the elements with `.status`, use `find` to select *within* the `row` element
                // $('.status').append('Offline');
                row.find('.status').append('Offline');
            } else {
                var streamStatus = data.stream.channel.status;
                var html = '<td class="stream">' + streamStatus + '</td>';
                row.find('.stream').html(html);
            }
            // apend it when you're done
            row.appendTo(table);
        }, 'jsonp');
    
        // make the same changes for channel
        //$.getJSON(channels + twitch[i], getChannels, 'jsonp');
    
    
    
      }
    
    });
    body {
      padding: 0;
      margin: 0;
      font-family: 'Oswald', sans-serif;
      font-size: 100%;
    }
    
    a {
      text-decoration: none;
    }
    
    #main {
      width: 600px;
      margin: 2% auto 0;
    }
    
    #header {
      padding: 0;
      margin: 0;
      background: #116466;
      color: #d1e8e2;
      line-height: 100px;
      width: 100%;
    }
    
    h1 {
      margin: 0 0 0 5%;
      font-size: 300%;
    }
    
    #row {
      background: #285277;
      width: 100%;
    }
    
    ul {
      margin: 0;
      padding: 0;
      list-style: none;
      display: flex;
      justify-content: space-between;
    }
    
    .choice {
      position: relative;
      text-align: center;
      width: 33%;
      background: #285277;
      padding: 5px 10px;
      display: inline-block;
      color: #d1e8e2;
      font-size: 150%;
    }
    
    .choice a {
      /*padding: 5px 20px;*/
      color: #d1e8e2;
    }
    
    #content {
      width: 100%;
      background: #efefef;
    }
    
    
    /*
    .choice a:active {
    	background: #1E3D59;
    }
    */
    
    .selected {
      background: #1E3D59;
    }
    
    .selected:after {
      content: '';
      position: absolute;
      top: 100%;
      right: 45%;
      width: 0;
      height: 0;
      border-top: solid 10px #1E3D59;
      border-left: solid 10px transparent;
      border-right: solid 10px transparent;
    }
    
    table {
      width: 600px;
    }
    
    tr {
      margin: 5px 0;
      display: flex;
      width: 100%;
      justify-content: space-between;
    }
    
    td {
      border-collapse: collapse;
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      display: inline-block;
      white-space: nowrap;
      overflow: hidden;
    }
    
    .game {
      padding-left: 10px;
      width: 100px;
      font-size: 120%;
      line-height: 75px;
      text-overflow: ellipsis;
    }
    
    .game a {
      color: #111;
    }
    
    .image {
      height: 75px;
      width: 75px;
    }
    
    .logo {
      padding: 3px 5px;
      box-sizing: border-box;
    }
    
    .stream {
      padding-right: 10px;
      width: 350px;
      display: inline-block;
      text-overflow: ellipsis;
      line-height: 75px;
    }
    <!DOCTYPE html>
    
    <html>
    
    <head>
      <title>Twitch.tv JSON API</title>
      <link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
      <script src="https://use.fontawesome.com/57c9bf8971.js"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    </head>
    
    <body>
      <div id='main'>
        <header id='header'>
          <h1>Twitch Streamers</h1>
        </header>
        <div id='row'>
          <ul>
            <li class='choice selected'><a href='#'>All</a></li>
            <li class='choice'><a href='#'>Online</a></li>
            <li class='choice'><a href='#'>Offline</a></li>
          </ul>
        </div>
        <div id='content'>
    
        </div>
      </div>
    </body>
    
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      相关资源
      最近更新 更多