ul 列表中的第一个和最后一个可见元素

6 javascript

我有一个可滚动的项目列表,我想从中检测( ) 列表中可见first的项目。lastul li

代码 :

ul {
  list-style-type: none;
  width: 400px;
  height: 70px;
  overflow-x: scroll;
  margin: 0;
  padding: 0;
  overflow: auto;
  white-space: nowrap;
}

ul li {
  /* float: left; */
  display: inline-block;
  width: 35px;
  margin: 3px;
  height: 35px;
  border: 1px solid red;
  white-space: pre-wrap;
  padding: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
  <li>Item 12</li>
  <li>Item 11</li>
  <li>Item 12</li>
  <li>Item 13</li>
  <li>Item 14</li>
  <li>Item 15</li>
  <li>Item 16</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

例如

这里,第一个是Item1,最后一个是Item7

在此输入图像描述

这里,第一个是Item5,最后一个是Item12

在此输入图像描述

注意:我只能使用 Javascript

nav*_*een 0

尝试这个。

// https://stackoverflow.com/a/41698614/17447
function isVisible(elem) {
  if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');
  const style = getComputedStyle(elem);
  if (style.display === 'none') return false;
  if (style.visibility !== 'visible') return false;
  if (style.opacity < 0.1) return false;
  if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
    elem.getBoundingClientRect().width === 0) {
    return false;
  }
  const elemCenter = {
    x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
    y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
  };
  if (elemCenter.x < 0) return false;
  if (elemCenter.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
  if (elemCenter.y < 0) return false;
  if (elemCenter.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
  let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y);
  do {
    if (pointContainer === elem) return true;
  } while (pointContainer = pointContainer.parentNode);
  return false;
}

document.querySelector('#get-visible-item')
  .addEventListener('click', evt => {
    const elmList = document.querySelectorAll('#items li');
    let first = last = -1;
    for (let i = 0; i < elmList.length; i++) {
      const elm = elmList[i];
      if (first !== -1 && !isVisible(elm)) {
        last = i - 1;
        break;
      }
      if (first === -1 && isVisible(elm)) {
        first = i;
      }
      if (i === elmList.length - 1) {
        last = i;
      }
    }
    console.clear();
    console.log(elmList[first]);
    console.log(elmList[last]);
  });
Run Code Online (Sandbox Code Playgroud)
ul {
  list-style-type: none;
  width: 400px;
  height: 70px;
  overflow-x: scroll;
  margin: 0;
  padding: 0;
  overflow: auto;
  white-space: nowrap;
}

ul li {
  /* float: left; */
  display: inline-block;
  width: 35px;
  margin: 3px;
  height: 35px;
  border: 1px solid red;
  white-space: pre-wrap;
  padding: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<ul id="items">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
  <li>Item 12</li>
  <li>Item 11</li>
  <li>Item 12</li>
  <li>Item 13</li>
  <li>Item 14</li>
  <li>Item 15</li>
  <li>Item 16</li>
</ul>
<button id="get-visible-item">Get Visible Item</button>
Run Code Online (Sandbox Code Playgroud)