Javascript性能:修复了Scroll上的表头和列

我正在尝试使用 Javascript滚动事件来修复表头,以操纵表头的顶级属性.

根据浏览器和屏幕分辨率,这种技术似乎有很大差异(我的主要网站访问者是Retina MBP).目前它口吃不好.它可能在这个小提琴中工作得很好,但实际上在桌面上会很慢而且很笨拙.

https://jsfiddle.net/taylorpalmer/exp057a5/

我需要能够滚动页面,并在滚过它时让表头粘住.

var allTh = document.querySelectorAll("th");
          var leftCells = document.querySelectorAll(".fixed-col");
          var latestKNownScrollX = 0;
          var latestKNownScrollY = 0;
          var ticking = false;


          var onScroll = function() {
            latestKNownScrollX = document.body.scrollLeft;
            latestKNownScrollY = document.body.scrollTop;
            requestTick();
          }

          function requestTick() {
            if (!ticking) {
              requestAnimationFrame(update);
            }
            ticking = true;
          }

          var immediate = true;

          var update = function() {
            console.log('scrolling');
            ticking = false;
            var currentScrollY = latestKNownScrollY;
            var currentScrollX = latestKNownScrollX;

            var translateHead = (currentScrollY) +"px"; 

            for(var i=0; i < allTh.length; i++ ) {
              allTh[i].style.top = translateHead;
            }

            var translateCell = currentScrollX + "px";

            for(var i=0; i < leftCells.length; i++ ) {
              leftCells[i].style.left = translateCell;
            }

          };

        window.addEventListener("scroll",onScroll);

我已经尝试过的事情:

>使用requestAnimationFrame() – 它当前已实现
> Debouncing scroll – 没有提高性能
>限制滚动 – 没有提高性能
>使用transform:translate()而不是top – 没有任何区别

我想过的事情,但不会奏效

>使用位置:固定或类似:标题单元格将失去其动态宽度并使表格毫无价值

解决方法

这样做怎么样?

https://jsfiddle.net/keikei/g3mt0rq6/

它的灵感来自this answer of the question

JS:

var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $row = $("#table-1 > tbody > tr").first().clone();
var $fixedHeader = $("#header-fixed")
  .append($header)
  .append($("<tbody>").append($row));

$(window).bind("scroll",function() {
  var offset = $(this).scrollTop();

  if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
    $fixedHeader.show();
  } else if (offset < tableOffset) {
    $fixedHeader.hide();
  }
});

HTML:

<body>
  <div id="wrap">
    <table id="header-fixed"></table>
    <table id="table-1">
      <thead>
        <tr>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
          <th>Test</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td class="fixed-col">Test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test<span style="position: relative">Relative</span></td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
          <td>test</td>
        </tr>
        <!-- and so on... --->
      </tbody>
    </table>
  </div>
</body>
<script>


</script>

CSS:

#header-fixed {
  position: fixed;
  top: 0px;
  display: none;
  z-index: 20;
}

#header-fixed > tbody {
  visibility: hidden;
}

#header-fixed > tbody > tr > td {
  height: 0;
  font-size: 0;
  border: none;
}

th {
  height: 100px;
  background: #999;
  color: white;
  position: relative;
  z-index: 10;
}

td {
  background-color: white;
  min-width: 100px;
  height: 100px;
  text-align: center;
  position: relative;
  z-index: 1;
}

.fixed-col {
  z-index: 5;
}

body,html {
  margin: 0;
}

thead {
  position: relative;
  z-index: 6;
}

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...