Я получаю ошибку «Уменьшение пустого массива без начального значения» при переборе элементов сетки - PullRequest
0 голосов
/ 29 августа 2018

У меня есть небольшой скрипт, роль которого состоит в том, чтобы помочь с адаптивной сеткой макетов, добавив класс 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 голосов
/ 29 августа 2018

Чтобы понять, что происходит, вы должны задаться вопросом, что уменьшает делает:

При первом вызове обратного вызова аккумулятор и currentValue могут принимать одно из двух значений. Если initialValue предоставлен в вызове redu (), то аккумулятор будет равен initialValue, а currentValue будет равен первому значению в массиве. Если значение initialValue не указано, аккумулятор будет равен первому значению в массиве, а currentValue будет равен второму.

Если вы предоставляете пустой массив без начального значения, скажите:

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

Тогда это больше не имеет смысла, поскольку вы не можете ни получить доступ к первому элементу массива, ни использовать начальное значение. Все, что вам нужно сделать, это предоставить начальное значение:

myArray.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");
      }
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...