遍历网格项时出现“减少没有初始值的空数组”错误

时间:2018-08-29 09:12:22

标签: javascript jquery html css grid

我有一个小的脚本,他的作用是通过将last-row类添加到位于最后一行的网格项来帮助响应网格布局:

function addLastRowClass() {
  $(".blocks_section").each(function() {
    var $grid_item = $(this).find(".news_box");
    var maxTop = $grid_item.removeClass("last-row").map(function() {
      var $item = $(this)
      return $item.position().top;
    }).get().reduce((acc, curr) => (curr > acc) ? curr : acc)

    $grid_item.filter(function() {
      var $item = $(this)
      return $item.position().top == maxTop;
    }).addClass("last-row");
  });
}

addLastRowClass();
$(window).resize(addLastRowClass);
.blocks_section {
  margin-top: 15px;
  display: flex;
  flex-wrap: wrap;
}

.blocks_section .news_box {
  display: flex;
  flex-direction: column;
  background: #fff;
  margin-bottom: 15px;
}

.blocks_section .news_box .content {
  border: 1px solid #d5d5d5;
  flex-grow: 1;
}

.blocks_section .news_box .title {
  padding: 8px 8px 0 8px;
}

.blocks_section .text {
  padding: 8px;
}

.blocks_section .title {
  font-size: 1.25rem;
  margin-bottom: 8px;
  text-transform: capitalize;
}

.blocks_section .text {
  margin-bottom: 8px;
  text-align: justify;
}

.blocks_section .thumbnail img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 767px) {
  .container {
    max-width: 100%;
  }
}

@media (max-width: 575px) {
  .container {
    max-width: 100%;
    padding-left: 0;
    padding-right: 0;
  }
  .blocks_section .news_box {
    padding-left: 5px;
    padding-right: 5px;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />

<h1 chass="h3">Lorem ipsum dolor</h1>
<div class="blocks_section">
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/ZeOrf.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/TICOa.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/ZeOrf.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/TICOa.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
</div>

<h1 chass="h3">Praesentium, provident</h1>
<div class="blocks_section">
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/ZeOrf.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/TICOa.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/ZeOrf.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
  <div class="news_box col-xs-12 col-sm-6 col-md-4">
    <div class="content">
      <div class="thumbnail"><img src="https://i.stack.imgur.com/TICOa.jpg"></div>
      <h2 class="title">Lorem ipsum dolor</h2>
      <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatem inventore eos in voluptas ab, aut pariatur, dolores atque neque consequuntur.</p>
    </div>
  </div>
</div>

它具有简单明了的逻辑,并且可以运行,但是在具有多个响应网格的复杂页面上,控制台将通过错误Reduce of empty array with no initial value,留下第二个(第三个,依此类推)没有此功能的网格。

问题:

  • 错误原因是什么?
  • 该问题的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

要了解正在发生的事情,您必须怀疑reduce在做什么:

  

第一次调用回调时,accumulator和currentValue可以是两个值之一。如果在reduce()的调用中提供了initialValue,则累加器将等于initialValue,而currentValue将等于数组中的第一个值。如果未提供initialValue,则累加器将等于数组中的第一个值,而currentValue将等于第二个值。

如果您提供没有行程值的空数组,请说:

[].reduce(() => {})

然后就没有意义了,因为您不能访问数组的第一个元素或使用初始值。您要做的就是提供一个初始值:

myArray.reduce(() => {}, [])

由于reduce函数正在使用数字,并且您要查找数字的最大值,因此可以使用-Infinity作为初始值:

myArray.reduce((acc, curr) => Math.max(acc, curr), -Infinity)

因此,对于您的用例:

function addLastRowClass() {
  $(".blocks_section").each(function() {
      var $grid_item = $(this).find(".news_box");
      var maxTop = $grid_item.removeClass("last-row").map(function() {
          var $item = $(this)
          return $item.position().top;
      }).get().reduce((acc, curr) => (curr > acc) ? curr : acc, -Infinity) //<--- Initial value provided here

      $grid_item.filter(function() {
          var $item = $(this)
          return $item.position().top == maxTop;
      }).addClass("last-row");
  });
}

另一方面,如果您可以使用数组解构,则只需执行以下操作即可:

function addLastRowClass() {
  $(".blocks_section").each(function() {
      var $grid_item = $(this).find(".news_box");
      var topPositions = $grid_item
          .removeClass("last-row")
          .map((i, el) => $(el).position().top)
          .get();
      var max_top = Math.max(...topPositions); // <-- Here
      $grid_item
          .filter((i, el) => $(el).position().top == maxTop)
          .addClass("last-row");
  });
}

编辑

只是注意到您正在尝试在那里做。仅当网格中没有任何项目时才会出现您的问题,但是在这种情况下您无需做任何事情,因此另一种解决方法是在处理之前检查项目的长度:

function addLastRowClass() {
  $(".blocks_section").each(function() {
      var $grid_item = $(this).find(".news_box");
      if($grid_item.length) {
          var maxTop = $grid_item.removeClass("last-row").map(function() {
              var $item = $(this)
              return $item.position().top;
          }).get().reduce((acc, curr) => (curr > acc) ? curr : acc)

          $grid_item.filter(function() {
              var $item = $(this)
              return $item.position().top == maxTop;
          }).addClass("last-row");
      }
  });
}