1

I'm using the scrollspy of Bootstrap-5.2 to update the displayed text whithin the scrollBox, when reaching the top or bottom part (pre-reload-item/post-reload-item). The funktion for the bottom shiftContentDown works fine, but for shiftContentUp it works the first time only. After that the scrollspy doesn't activate the reload-top element anymore unless I scroll down to the post-reload-item (->reload-bottom activates -> shiftContentDown fires) and then up again.

I suspect it has something to do with the line document.getElementById('scrollBox').scrollBy(0, count * 24). Without it the new content of the pre-reload-item would be in fokus and the reload-top element stays active. With it the previous content of the pre-reload-item now part of the mid-reload-item stays visible and the reload-top element is no longer active. I'd expect it to activate again if I scroll up now, but for some reason it doesn't.

let nextIndex = 0;
let allContent = [];
let displayed = [0, 0]
let eof = false;
let pre = document.getElementById('pre-reload-item');
let mid = document.getElementById('mid-reload-item');
let post = document.getElementById('post-reload-item');

document.getElementById('scrollBox').addEventListener('activate.bs.scrollspy', () => {
  let current = document.querySelector('#indexBox > a.active');
  if (current === document.getElementById('reload-bottom')) {
    shiftContentDown()
  } else if (current === document.getElementById('reload-top')) {
    shiftContentUp()
  }
});

function shiftContentDown(count = 100, buffer = 0.5) {
  let shift = allContent.length - displayed[1];
  if (!eof && shift < count) {
    getMoreContent(nextIndex);
  } else {
    let addition = allContent.slice(displayed[1], displayed[1] + count);
    addition.forEach(l => {
      if (pre.childElementCount >= (count * buffer)) {
        pre.removeChild(pre.childNodes[0]);
        displayed[0]++;
      }
      if (mid.childElementCount >= (count * (1 + 2*buffer)))
        pre.appendChild(mid.childNodes[0]);
      if (post.childElementCount >= (count * buffer) || post.childNodes.length > mid.childNodes.length)
        mid.appendChild(post.childNodes[0]);
      post.appendChild(l);
      displayed[1]++;
    });
  }
}

function shiftContentUp(count = 100) {
  let addition = allContent.slice(Math.max(displayed[0] - count, 0), displayed[0]);
  addition.reverse().forEach(l => {
    pre.insertBefore(l, pre.childNodes[0]);
    displayed[0]--;
    mid.insertBefore(pre.childNodes[pre.childElementCount - 1], mid.childNodes[0]);
    post.insertBefore(mid.childNodes[mid.childElementCount - 1], post.childNodes[0]);
    post.removeChild(post.childNodes[post.childElementCount - 1]);
    displayed[1]--;
  });
  document.getElementById('scrollBox').scrollBy(0, count * 24);
}

function getMoreContent(index, chunkSize=100, last=1000) {
  for (let i=0; i < chunkSize; i++) {
    if (nextIndex < last) {
      let newLineNode = document.createElement('div');
      newLineNode.innerHTML = '----- ' + (nextIndex++) + ' -----';
      allContent.push(newLineNode);
    } else {
      eof = true;
    }
  }
  shiftContentDown();
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">

<div id="indexBox" class="list-group" style="display: none">
  <a id="reload-bottom" class="list-group-item list-group-item-action" href="#post-reload-item">reload bottom</a>
  <a id="reload-top" class="list-group-item list-group-item-action" href="#pre-reload-item">reload top</a>
</div>
<div id="scrollBox" data-bs-spy="scroll" data-bs-target="#indexBox" data-bs-smooth-scroll="true" data-bs-offset="0" class="scrollspy-example" tabindex="0" style="height: 300px; overflow-y: scroll">
  <div id="pre-reload-item" class="text-bg-danger" style="white-space: pre-line"></div>
  <div id="mid-reload-item" class="text-bg-info" style="white-space: pre-line"></div>
  <div id="post-reload-item" class="text-bg-danger" style="white-space: pre-line"></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
lilninj
  • 11
  • 2

0 Answers0