Setting the position of a navigation highlight
Refactoring

Disclaimer: Sorry, I didn't have a solid chunk of time to test the code, so please consider it as a direction rather than an exact prescription.



It's always possible to break away from loop execution interfering keywords like continue and break. It is also almost always possible to quickly rewrite the code in a "more functional" way. Question is, what exactly is the motivation.

First, in functional world it all about function. And even though my code below does not use function composition, I'm adding getPosition(), isCloseToTop(), and isScrollAfterPosition() to simplify a few conditions. Another benefit of that is that these local functions' names are replacing the ugly comments.

Second, nav.positions.findIndex(...) is used to find out whether there's an item close to top. This is made as an independent step in the code and IMO it's more expressive this way.

If there's no item close to the top of window, we can try to find the last position before the scroll. Again, now it's implemented as a dedicated step (via map() and filter()).

Hopefully, it's now closer to what you wanted the code to be.

function setHighlightPosition(nav) {
  const scrollTop = window.scrollY;
  const scrollMiddle = scrollTop + (window.innerHeight / 2);

  const getPosition = item =&gt; document.getElementById(item.id).offsetTop;
  const isCloseToTop = position =&gt;
    Math.abs(position - scrollTop) &lt; 25 ||
    scrollTop &lt; position &amp;&amp; position - scrollTop &lt; 50;
  const isScrollAfterPosition = position =&gt; scrollMiddle &gt; position;

  const indexOfItemCloseToTop = nav.positions.findIndex(item =&gt; item.targeted &amp;&amp; isCloseToTop(getPosition(item)));

  if (indexOfItemCloseToTop &gt;= 0) {
    highlightItem = indexOfItemCloseToTop;
  } else {
    const positionsBeforeScroll = nav.positions
      .map((item, itemIndex) =&gt; (item.targeted &amp;&amp; isScrollAfterPosition(getPosition(item))) ? itemIndex : null)
      .filter(index =&gt; index !== null);
    highlightItem = positionsBeforeScroll[positionsBeforeScroll.length - 1];
  }

  const documentEnd = document.documentElement.scrollHeight - window.innerHeight;
  if (scrollTop === documentEnd) {
    highlightItem = nav.positions.length - 1;
  }

  const highlight = document.getElementById('nav-highlight');
  highlight.style.transform = `translateY(${nav.positions[highlightItem].position}px)`;
  highlight.dataset.position = highlightItem;
}


BTW, I moved variable declarations around so that the declarations are located next to their first usages. This reduces brain cycles and eliminates the need of scrolling the code up and down.