'JavaScript - Show More from DOM array

Trying to show some element on first render and when user click on Load More will show some more data and this will happen until all element show on each click;

const itemPerPage = 2;

Here is what I had tried with -

document.addEventListener('DOMContentLoaded', () => {
    const itemPerPage = 2;
    const AllItems = [...document.querySelectorAll('.item')];
    const btnLoadMore = document.getElementsByClassName('btn-loadmore')[0];

    if (itemPerPage > 0 && AllItems?.length > 0) {
        var firstRenderItems = Array.from(AllItems).slice(0, itemPerPage);
        if (firstRenderItems?.length > 0) {
            firstRenderItems.forEach(element => {
                element.style.display = 'block';
            });
        }
    }
    if (btnLoadMore && AllItems?.length > itemPerPage) {
        btnLoadMore.style.display = 'block';
    }
});
.container{
  display:block;
  padding: 20px;
}
.item{
  display: none;
  align-items: center;
  justify-content: flex-start;
  min-height: 70px;
  border-bottom: 1px solid #ddd;
}
.btn-loadmore{
  display:none;
}
<html>
<head>
</head>

<body>
<div class='container'>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
  <div class='item'>Content 1</div>
</div>
  <button class='btn-loadmore'>Load More</button>
</body>
</htmL>


Solution 1:[1]

To show 2 items per page, one needs to add the button onclick handler using something similar to below:

Code Snippet

const itemPerPage = 2;
const AllItems = [];

const loadItems = (currLastItem) => {
  AllItems.slice(
    currLastItem, currLastItem + itemPerPage
  ).forEach(
    el => el.style.display = 'block'
  );
};

document.addEventListener('DOMContentLoaded', () => {
    let currLastItem = 0;
    [...document.querySelectorAll('.item')].forEach(el => AllItems.push(el));
    const btnLoadMore = document.getElementsByClassName('btn-loadmore')[0];

    if (AllItems?.length > 0) {
      loadItems(currLastItem);
      currLastItem += itemPerPage;
    }
    if (btnLoadMore && currLastItem < AllItems?.length) {
      btnLoadMore.style.display = 'block';
      btnLoadMore.onclick = () => {
        loadItems(currLastItem);
        currLastItem += itemPerPage;
        if (currLastItem >= AllItems?.length) {
          btnLoadMore.style.display = 'none';
        }
      }
    }
});
.container{
  display:block;
  padding: 20px;
}
.item{
  display: none;
  align-items: center;
  justify-content: flex-start;
  min-height: 70px;
  border-bottom: 1px solid #ddd;
}
.btn-loadmore{
  display:none;
}
<html>
<head>
</head>

<body>
<div class='container'>
  <div class='item'>Content 1</div>
  <div class='item'>Content 2</div>
  <div class='item'>Content 3</div>
  <div class='item'>Content 4</div>
  <div class='item'>Content 5</div>
  <div class='item'>Content 6</div>
  <div class='item'>Content 7</div>
  <div class='item'>Content 8</div>
  <div class='item'>Content 9</div>
  <div class='item'>Content 10</div>
  <div class='item'>Content 11</div>
  <div class='item'>Content 12</div>
  <div class='item'>Content 13</div>
  <div class='item'>Content 14</div>
  <div class='item'>Content 15</div>
</div>
  <button class='btn-loadmore'>Load More</button>
</body>
</htmL>

Solution 2:[2]

Is this what you want?

document.addEventListener('DOMContentLoaded', () => {
  let current = 2
  const AllItems = [...document.querySelectorAll('.item')]
  const btnLoadMore = document.getElementById('btn')

  if (AllItems.length > 0) {
    let firstRenderItems = Array.from(AllItems).slice(0, current);
    if (firstRenderItems.length > 0) {
        firstRenderItems.forEach(element => {
            element.style.display = 'block'
        })
    }
  }
  
  btnLoadMore.addEventListener('click', () => {
     if (AllItems.length > current) {
        current++
        if(current >= AllItems.length) btnLoadMore.style.display = 'none' 
        const list = Array.from(AllItems).slice(0, current)
        list[current - 1].style.display = 'block'
     }
  })
  
})
.container{
  display:block;
  padding: 20px;
}
.item{
  display: none;
  align-items: center;
  justify-content: flex-start;
  min-height: 70px;
  border-bottom: 1px solid #ddd;
}
<html>
<head>
</head>

<body>
<div class='container'>
  <div class='item'>Content 1</div>
  <div class='item'>Content 2</div>
  <div class='item'>Content 3</div>
  <div class='item'>Content 4</div>
  <div class='item'>Content 5</div>
  <div class='item'>Content 6</div>
  <div class='item'>Content 7</div>
  <div class='item'>Content 8</div>
  <div class='item'>Content 9</div>
  <div class='item'>Content 10</div>
</div>
  <button class='btn-loadmore' id='btn'>Load More</button>
</body>
</htmL>

Solution 3:[3]

Loads 2 items each time you click load more and hides the button once all items are loaded. I didn't see a reason why the items array couldn't be used to track the remaining hidden items so I used items.splice() instead of counting and comparing length to item count.

var items = [];
const itemPerPage = 2;
var btnLoadMore;

function buttonToggle() {
  if (btnLoadMore && items.length) {
    btnLoadMore.style.display = 'block';
  } else {
    btnLoadMore.style.display = 'none';
  }
}

function loadMore() {
  if (items.length) {
    items.splice(0, itemPerPage).forEach(item => {
      item.style.display = 'block';
    })
  }
  buttonToggle();
}

document.addEventListener('DOMContentLoaded', () => {

  items = [...document.querySelectorAll('.item')];
  btnLoadMore = document.querySelector('.btn-loadmore');

  if (itemPerPage > 0 && items.length) {
    loadMore();
  }

});
.container {
  display: block;
  padding: 20px;
}

.item {
  display: none;
  align-items: center;
  justify-content: flex-start;
  min-height: 70px;
  border-bottom: 1px solid #ddd;
}

.btn-loadmore {
  display: none;
}
<html>

<head>
</head>

<body>
  <div class='container'>
    <div class='item'>Content 1</div>
    <div class='item'>Content 2</div>
    <div class='item'>Content 3</div>
    <div class='item'>Content 4</div>
    <div class='item'>Content 5</div>
    <div class='item'>Content 6</div>
    <div class='item'>Content 7</div>
    <div class='item'>Content 8</div>
    <div class='item'>Content 9</div>
    <div class='item'>Content 10</div>
    <div class='item'>Content 11</div>
    <div class='item'>Content 12</div>
    <div class='item'>Content 13</div>
    <div class='item'>Content 14</div>
    <div class='item'>Content 15</div>
  </div>
  <button class='btn-loadmore' onclick='loadMore()'>Load More</button>
</body>

</htmL>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3