手写虚拟列表

  • 虚拟列表是按需显示的一种技术,可以根据用户的滚动,不必渲染所有列表项,而只是渲染可视区域内的一部分列表元素的技术。
  • 在日常的使用中,有很多优秀的虚拟列表使用库,如之前写过的react-virtualized虚拟滚动(https://blog.csdn.net/weixin_43760969/article/details/121012775)等
  • 这边文章主要是手写简单的虚拟列表,纯js实现
  • 使用requestAnimationFrame进行节流处理
  • window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>虚拟列表</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      list-style: none
    }

    .outside {
      position: relative;
      margin: 100px auto;
      height: 150px;
      width: 200px;
      overflow: auto;
      text-align: left;
    }

    .main {
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
    }

    li {
      box-sizing: border-box;
      border: 1px dashed #ddd;
      height: 30px;
      text-indent: 10px;
      font-size: 14px;
      color: #444;
      line-height: 30px;
    }
  </style>
</head>

<body>
  <div style="text-align: center">
    <div class="outside" onscroll="onScroll()">
      <div class="inside"></div>
      <ul class="main"></ul>
    </div>
  </div>
  <script>
    function onScroll() {
      //需要做节流处理
      cancelAnimationFrame(rafId)
      rafId = requestAnimationFrame(handleScroll)
    }
    function handleScroll() {
      const { scrollTop, clientHeight } = outside
      // 计算每页可以放多少个li
      const pageSize = Math.ceil(clientHeight / liHeight)
      // 当前处于第几页
      const currentPage = Math.floor(scrollTop / (liHeight * pageSize))
      if (currentPage !== indexPage) {
        console.log('upDate', currentPage)
        indexPage = currentPage
        // 截取数据的初始位置
        const startIndex = currentPage * pageSize
        // 截取数据的结束位置(等于2页的数据)
        const endIndex = startIndex + pageSize * 2
        const newData = data.slice(startIndex, endIndex)
        ul.innerHTML = newData.map(o => `<li>序号:${o.index}${o.name}</li>`).join('')
        ul.style.transform = `translate3d(0, ${startIndex * liHeight}px, 0)`
      }
    }
    // 源数据
    const data = new Array(99999).fill('').map((v, i) => ({ index: i + 1, name: Math.random().toString(16).slice(-10) }))
    // li的高度
    const liHeight = 30
    const outside = document.querySelector('.outside')
    // 生产真实滚动条
    document.querySelector('.inside').style.height = `${data.length * liHeight}px` 
    const ul = document.querySelector('ul')
    // 旧页码
    let indexPage = -1
    // 定时器
    let rafId = 0
    handleScroll()
  </script>
</body>

</html>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于手写Tomcat的时序图,由于没有提供具体的代码或步骤,我无法为您绘制完整的时序图。但是,我可以简要地介绍一下手写Tomcat的一般步骤。 1. 创建Tomcat对象:首先,您需要创建一个Tomcat对象,用于启动和管理Tomcat服务器。这可以通过实例化Tomcat类来完成。 2. 配置Tomcat:接下来,您需要配置Tomcat服务器。这涉及设置端口号、虚拟主机、上下文路径、静态资源路径等。您可以使用Tomcat对象的相关方法来完成这些配置。 3. 创建并配置Servlet:在Tomcat中,Servlet是基于Java的Web组件,用于处理HTTP请求和生成HTTP响应。您需要创建一个实现Servlet接口的类,并将其配置到Tomcat中。 4. 添加Servlet映射:一旦Servlet创建好并配置到Tomcat中,您需要将其与特定的URL模式进行映射。这可以通过调用Tomcat对象的addServlet方法来实现。 5. 启动Tomcat:完成上述配置后,您可以调用Tomcat对象的start方法来启动Tomcat服务器。此时,Tomcat将开始监听配置的端口并等待HTTP请求。 6. 处理HTTP请求:一旦Tomcat启动并监听端口,它将开始接收和处理HTTP请求。当收到请求时,Tomcat会根据配置的Servlet映射找到相应的Servlet,并将请求转发给它进行处理。 7. 生成HTTP响应:Servlet接收到请求后,会执行相应的逻辑来生成HTTP响应。这可能涉及与数据库交互、处理表单数据、生成动态内容等操作。 8. 返回HTTP响应:一旦Servlet生成了HTTP响应,它将通过Tomcat服务器发送回客户端。 请注意,以上步骤只是手写Tomcat过程的一般概述,并不包括所有的细节和具体实现。如果您需要更详细的信息,建议参考相关的文档或教程。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [手写tomcat](https://download.csdn.net/download/qq_35181163/10455229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [高性能服务中间件Tomcat工作原理解析(三)](https://blog.csdn.net/worn_xiao/article/details/122261461)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值