可见容器内的中心点有溢出

时间:2018-07-25 15:51:28

标签: javascript html css

如您所见fiddle here

,如何使点在可见容器溢出中居中

单击第一个点1到3时,它们按预期的方式贴在顶部,从第4点和第5点开始,他们应调整顶部距离,以使其居中于容器,然后单击6th,7th,8th停留在底部。

当我增加总点数(比如说9或10点)时,该示例当然不起作用。我找不到正确的数学公式,知道吗?

非常感谢。

const ul = document.getElementsByClassName('list')[0];
const list = document.querySelectorAll('.list li');
const total = 5;
const offset = total / 2;
const circleTotalHeight = 40;

const totalViewable = 5;
const totalHeight = circleTotalHeight * list.length;
const totalViewableHeight = total * circleTotalHeight;
const limitTopOffset = totalViewableHeight - totalHeight; // -120
const halfViewableCount = Math.ceil(totalViewable / 2); //3
const halfTotalCount = Math.ceil(list.length / 2); //4
const centerViewablePx = 160;

let activeIndex = 0;
let nthActiveIndex = activeIndex + 1;

Array.prototype.forEach.call(list, (li) => {
  li.addEventListener('click', (e) => {
    let data = e.target.getAttribute("data-number");
    const prevElement = `[data-number="${activeIndex}"]`;
    const nextElement = `[data-number="${data}"]`;

    ul.querySelector(nextElement).style.color = '#FFF';
    ul.querySelector(prevElement).style.color = '#000';

    nthActiveIndex = parseInt(data) + 1;
    var nthActiveOffset = nthActiveIndex - halfViewableCount;
    if (data < halfTotalCount && data < halfViewableCount) {
      ul.style.top = '0';
    } else if (data > halfTotalCount && data > halfViewableCount) {
      ul.style.top = `${limitTopOffset}px`;
    } else {
      let midTopOffset = 0;
      if (data < halfTotalCount) {
        midTopOffset = (nthActiveIndex * circleTotalHeight) / 2;
      } else {
        midTopOffset = (nthActiveIndex * circleTotalHeight) - 160;
      }

      const dotContainerTopValue = midTopOffset + limitTopOffset;
      //alert(midTopOffset);
      if (dotContainerTopValue >= 0) {
        ul.style.top = '0';
      } else {
        ul.style.top = `${dotContainerTopValue}px`;
      }
    }

    activeIndex = data;
  });
})
.list {
  list-style-type: none;
  position: absolute;
  top: 0;
  left: 0;
  padding: 0;
  margin: 0;
}
.list li {
  width: 20px;
  height: 20px;
  display: block;
  background: red;
  border-radius: 50%;
  text-align: center;
  margin-top: 10px;
  margin-bottom: 10px;
  cursor: pointer;
  font-size: 12px;
  float: right;
}
.list-container {
  height: 200px;
  width: 20px;
  background: #42b549;
  opacity: 0.5;
  position: relative;
  margin: auto;
  top: 160px;
}
<div class="list-container">
  <ul class="list">
    <li data-number="0">1</li>
    <li data-number="1">2</li>
    <li data-number="2">3</li>
    <li data-number="3">4</li>
    <li data-number="4">5</li>
    <li data-number="5">6</li>
    <li data-number="6">7</li>
    <li data-number="7">8</li>
  </ul>
</div>

1 个答案:

答案 0 :(得分:0)

我想我找到了一个解决方案,只是分享here。我希望不要错过任何事情。

const ul = document.getElementsByClassName('list')[0];
const list = document.querySelectorAll('.list li');
const total = 5;
const offset = total / 2;
const circleTotalHeight = 30;

const totalViewable = 5;
const totalHeight = circleTotalHeight * list.length;
const totalViewableHeight = totalViewable * circleTotalHeight;
const limitTopOffset = totalViewableHeight - totalHeight; // -120
const halfViewableCount = totalViewable / 2; //2.5
const halfTotalCount = Math.ceil(list.length / 2); //4
const diffTotalAndView = list.length - totalViewable; // 3


let activeIndex = 0;
let nthActiveIndex = activeIndex + 1;

Array.prototype.forEach.call(list, (li) => {
  li.addEventListener('click', (e) => {
    let data = e.target.getAttribute("data-number");
    const prevElement = `[data-number="${activeIndex}"]`;
    const nextElement = `[data-number="${data}"]`;

    ul.querySelector(nextElement).style.color = '#FFF';
    ul.querySelector(prevElement).style.color = '#000';

    nthActiveIndex = parseInt(data) + 1;
    var nthActiveOffset = nthActiveIndex - halfViewableCount;
    var nthOffset = Math.floor(nthActiveIndex - halfViewableCount);

    if (nthOffset >= 0) {

      //console.log(nthOffset);
      if (nthOffset < diffTotalAndView) {
        var topDistance = -1 * (nthOffset * circleTotalHeight);
        ul.style.top = `${topDistance}px`;
      } else {
        ul.style.top = `${limitTopOffset}px`;
      }

    } else {
      ul.style.top = '0';
    }

    activeIndex = data;
  });
})