开发者问题收集

增加数字时单击按钮时出现“未捕获类型错误:无法读取未定义的属性‘名称’”

2017-03-16
769

问题

我有两个按钮 .btn-previousbtn-next 。单击其中一个按钮会为变量 var currentNumber = 0, 加一或减一。但是,当用户单击 next 一直到最后一个人或单击 previous 一直到数组中的第一个人时,我会看到错误 Uncaught TypeError: Cannot read property 'name' of undefined

我尝试过:

  • 切换 if 语句中的比较运算符
  • 隔离可能导致问题的 if 语句部分,

$(".btn-previous span").html(players[currentNumber - 1].name); $(".btn-next span").html(players[currentNumber + 1].name);

目标

  • 单击下一个或上一个按钮时,更改名称、描述和按钮文本,其中包含数组中下一个和上一个人员的姓名
  • 如果用户位于数组末尾,则隐藏下一个按钮,显示上一个
  • 如果他们位于数组开头,则隐藏上一个按钮,显示下一个

这是问题的 JSFiddle:

https://jsfiddle.net/6xm96vw9/16/

scripts.js

$(function(){

  var currentNumber = 0;

    // Key players
    // Sets the default values as the first key player
    $(".player__info--name").html(players[currentNumber].name);
    $(".player__info--desc").html(players[currentNumber].description);
    $(".btn-next span").html(players[currentNumber + 1].name);

    if (currentNumber <= 0) {
      $(".btn-previous").hide();
      $(".controls__inner").css("justify-content", "flex-end");
    } else {
      $(".btn-previous").show();
      $(".controls__inner").css("justify-content", "space-between");
    }

    // When a person clicks on the previous button
    $(".btn-previous").on("click", function() {

      if (currentNumber > 0) {
        currentNumber = currentNumber - 1;

        $(".btn-previous").show();
        $(".btn-next").show();
        $(".controls__inner").css("justify-content", "flex-end");
        $(".player__info--name").html(players[currentNumber].name);
        $(".player__info--desc").html(players[currentNumber].description);
        $(".btn-previous span").html(players[currentNumber - 1].name);
        $(".btn-next span").html(players[currentNumber + 1].name);
      } else {
        $(".btn-previous").hide();
        $(".btn-next").show();
        $(".controls__inner").css("justify-content", "space-between");
      }
    });

    // When a person clicks on the next button
    $(".btn-next").on("click", function() {


      // It's six because it's zero-indexed
      if (currentNumber < 6 ) {
        currentNumber = currentNumber + 1;
        console.log(currentNumber);

        $(".player__info--name").html(players[currentNumber].name);
        $(".player__info--desc").html(players[currentNumber].description);
        $(".btn-previous span").html(players[currentNumber - 1].name);
        $(".btn-next span").html(players[currentNumber + 1].name);

        $(".btn-previous").show();
        $(".btn-next").show();
        $(".controls__inner").css("justify-content", "flex-start");
      } else {
        $(".btn-previous").show();
        $(".btn-next").hide();
        $(".controls__inner").css("justify-content", "space-between");
      }
    });


  });


var players = [
  {
    "id": 1,
    "name": "name1",
    "description": "description1"
  },
  {
    "id": 2,
    "name": "name2",
    "description": "description2"
  },
  {
    "id": 3,
    "name": "name3",
    "description": "description3"
  },
  {
    "id": 4,
    "name": "name4",
    "description": "description4"
  },
  {
    "id": 5,
    "name": "name5",
    "description": "description5"
  },
  {
    "id": 6,
    "name": "name6",
    "description": "description6"
  },
  {
    "id": 7,
    "name": "name7",
    "description": "description7"
  }
]

index.html

<div class="player__info">
    <div class="player__info--inner-group">
        <div class="player__image--wrapper">
            <div class="player__image"></div>
        </div> <!-- player__image--wrapper -->

        <div class="player__info--inner">
            <p class="player__info--header">Key Players</p>
            <p class="player__info--name">tk-name</p>

            <div class="player__info--group">
                <p class="player__info--desc"></p>
            </div>
        </div> <!-- player__info--inner -->
    </div> <!-- player__info--inner-group -->
</div> <!-- player__info -->

<div class="controls">
    <div class="controls__inner">
        <button class="btn btn-previous">Previous: <span class="is-bold">tk-name</span></button>
        <button class="btn btn-next">Next: <span class="is-bold">tk-name</span></button>
    </div>
</div>

3个回答

在更新 currentNumber 后运行检查,如果它位于范围末尾,则隐藏该按钮,否则更新该按钮的文本。

$(function() {

  var currentNumber = 0;

  // Key players
  // Sets the default values as the first key player
  $(".player__info--name").html(players[currentNumber].name);
  $(".player__info--desc").html(players[currentNumber].description);
  $(".btn-next span").html(players[currentNumber + 1].name);

  if (currentNumber <= 0) {
    $(".btn-previous").hide();
    $(".controls__inner").css("justify-content", "flex-end");
  } else {
    $(".btn-previous").show();
    $(".controls__inner").css("justify-content", "space-between");
  }

  // When a person clicks on the previous button
  $(".btn-previous").on("click", function() {

    currentNumber = currentNumber - 1;

    $(".btn-next").show();
    $(".controls__inner").css("justify-content", "flex-end");
    $(".player__info--name").html(players[currentNumber].name);
    $(".player__info--desc").html(players[currentNumber].description);
    // after you've decremented your index, check to see if you're at the beginning
    if (currentNumber == 0)
      // if you are, hide the previous button
      $(".btn-previous").hide();
    else {
      // if you aren't, update the previous button's text
      $(".btn-previous span").html(players[currentNumber - 1].name);
      // make sure the previous button is shown
      $(".btn-previous").show();
    }
    $(".btn-next span").html(players[currentNumber + 1].name);
  });

  // When a person clicks on the next button
  $(".btn-next").on("click", function() {
    currentNumber = currentNumber + 1;

    $(".btn-previous").show();
    $(".player__info--name").html(players[currentNumber].name);
    $(".player__info--desc").html(players[currentNumber].description);
    $(".btn-previous span").html(players[currentNumber - 1].name);
    if (currentNumber == (players.length - 1))
      // if at the end of your list, hide the next button
      $(".btn-next").hide();
    else {
      // if not, show the next button and update its text
      $(".btn-next").show();
      $(".btn-next span").html(players[currentNumber + 1].name);
    }
    $(".controls__inner").css("justify-content", "flex-start");
  });


});


var players = [{
    "id": 1,
    "name": "name1",
    "description": "description1"
  },
  {
    "id": 2,
    "name": "name2",
    "description": "description2"
  },
  {
    "id": 3,
    "name": "name3",
    "description": "description3"
  },
  {
    "id": 4,
    "name": "name4",
    "description": "description4"
  },
  {
    "id": 5,
    "name": "name5",
    "description": "description5"
  },
  {
    "id": 6,
    "name": "name6",
    "description": "description6"
  },
  {
    "id": 7,
    "name": "name7",
    "description": "description7"
  }
]
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="player__info">
  <div class="player__info--inner-group">
    <div class="player__image--wrapper">
      <div class="player__image"></div>
    </div>
    <!-- player__image--wrapper -->

    <div class="player__info--inner">
      <p class="player__info--header">Key Players</p>
      <p class="player__info--name">tk-name</p>

      <div class="player__info--group">
        <p class="player__info--desc"></p>
      </div>
    </div>
    <!-- player__info--inner -->
  </div>
  <!-- player__info--inner-group -->
</div>
<!-- player__info -->

<div class="controls">
  <div class="controls__inner">
    <button class="btn btn-previous">Previous: <span class="is-bold">tk-name</span></button>
    <button class="btn btn-next">Next: <span class="is-bold">tk-name</span></button>
  </div>
</div>

添加了一些注释以帮助解释。基本上,您想在更新当前索引后检查您是否位于范围末尾。如果位于末尾,则隐藏相应的按钮,如果不是末尾,则显示该按钮并更新其内容。

larz
2017-03-16

发生此错误的原因是,当您位于播放器索引 0 时,您正在显示 Prev Next 按钮,这导致尝试获取 players[0 - 1] 对象。

同样的事情发生在最后一个 Next 按钮上,该按钮尝试获取 players[6 + 1]

E. Sundin
2017-03-16

您尝试访问数组中不存在的索引。

一旦 currentNumber + 1 的值大于 6, players[ 7 ] 将未定义。因此,会出现错误。

如果 currentNumber - 1 的值小于 0,情况也是如此。

gargsms
2017-03-16