js scroll 判断 横向滚动还是 纵向滚动_无限滚动时间组件

bc44a129f6ef77fbc6965576c9c86506.png

思路

首先,高度一直增加,才有无限滚动的可能

那高度如何一直增加呢,联想到拼接,一块拼着一块,这样高度才能一直延续下去

css里面有实现这个的方式吗?有的,相对定位(记得去年面试的时候解答的是使用transform,通过两个块平移拼接的方式,模拟无限滚动的效果,当时字节面试官点了点头说思路可以,你再回去试试,但我这一回去,隔了一年都没有去试... 直到最近又去字节面试,被问到position有几种定位方式,才想起这件事情来)

relative

相对定位在MDN中的定义如下:

"该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。"

例子演示

相对定位的元素是在文档中的正常位置偏移给定的值,但是不影响其他元素的偏移。下面的例子中,注意未应用定位的其它元素是按照 "Two" 在正常位置的情况下进行布局的。

493a4421ba250b39f2aaa91423fd3087.png

最终效果,就是相对定位的元素并未脱离文档流,原来的空间还是占着的,但是又能基于原来的位置进行偏移,并且不影响其他元素,好家伙这就是我们想要的效果

实现

有了思路和实现的手段之后,我们就可以先来实现着试一试

1. 先写不带js的,通过手动在浏览器里修改样式,模拟下实现

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .ul-ct {
      list-style: none;
      width: 60px;
      padding: 0;
      text-align: center;
      margin: 0;
      height: 216px;
      overflow: scroll;
      -ms-overflow-style: none;
      scrollbar-width: none;
    }
    .ul-ct::-webkit-scrollbar {
      display: none;
    }
    .lis1-ct,
    .lis2-ct {
      position: relative;
    }

    .lis1-ct {
      background-color: green;
    }
    .lis2-ct {
      background-color: red;
    }
  </style>
</head>
<body>
  <ul class="ul-ct">
    <div class="lis1-ct" style="top: 0;">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
    </div>
    <div class="lis2-ct" style="top: 0;">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
    </div>
  </ul>
</body>
</html>

在浏览器手动修改样式
一共两个块拼接,当第二个都滚动底时(没有可滚动的剩余高度了),那么这时候将第一个块的top偏移两个块的高度的和,然后第一个又滚动底时(没有可滚动的剩余高度了),那么这时候将第二个块的top偏移两个块的高度的和,以此往复,便形成了循环...

效果如下

3610069ad9f212368b1b20f289382574.gif

2. 找到规律后,再把js代码添加进去,顺便修改下样式,最终代码如下

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .ul-ct {
      list-style: none;
      width: 60px;
      padding: 0;
      text-align: center;
      margin: 0;
      height: 90px;
      overflow: scroll;
      -ms-overflow-style: none;
      scrollbar-width: none;
      cursor: pointer;
    }
    .ul-ct::-webkit-scrollbar {
      display: none;
    }
    .lis1-ct,
    .lis2-ct {
      position: relative;
    }
  </style>
</head>
<body>
  <ul class="ul-ct">
    <div class="lis1-ct" style="top: 0;">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
    </div>
    <div class="lis2-ct" style="top: 0;">
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
    </div>
  </ul>
  <script>
    window.onload = function () {
      const el = document.querySelector('.ul-ct');
      const lis1 = document.querySelector('.lis1-ct');
      const lis2 = document.querySelector('.lis2-ct');
      el.addEventListener('scroll', () => {
        const scrollTop = el.scrollTop;
        const clientHeight = el.clientHeight;
        const scrollHeight = el.scrollHeight;
        const blockHeight = lis1.clientHeight;
        if (scrollHeight > clientHeight && scrollTop + clientHeight === scrollHeight) {
          const lis1Top = parseInt(lis1.style.top), lis2Top = parseInt(lis2.style.top);
          if (lis1Top === lis2Top) {
            lis1.style.top = (lis1Top + blockHeight * 2) + 'px';
          } else {
            lis2.style.top = (lis2Top + blockHeight * 2) + 'px';
          }
        }
      });
    };
  </script>
</body>
</html>

最终效果如下

effb2068de513bdd9cd9a7ba6219edfd.gif

项目地址

rencoo/infinite-scrolling-timepicker

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值