【问题标题】:Fixed row/column header with css and javascript使用 css 和 javascript 修复行/列标题
【发布时间】:2018-06-19 08:00:39
【问题描述】:

我需要一个带有固定列/行标题的布局。经过一些“反复试验”后,我想出了这个解决方案(参见jsfiddle)。只有右下窗格是可滚动的,并且标题是使用 javascript 移动的。

在 Chrome 中一切都很好,但在 IE/Edge 中滚动很慢:左右部分不会同时滚动,但延迟最小(尤其是内容“大”),这很烦人.你有什么解决办法吗?我必须找到另一种方法来达到结果(在这种情况下你有什么建议吗)?

$(function() {
    init();

});

function init(){
    var div1=$("#mainContainer");
    
    var oldScrollTop = $(div1).scrollTop();

    $(div1)
        .scroll( function () {
            if (oldScrollTop == $(div1).scrollTop()){
                scrollRowTableHeader(); //horizontal scroll
            }else {
                oldScrollTop = $(div1).scrollTop();
                scrollColumnTableHeader(); //vertical scroll
            }
        });

}

function scrollColumnTableHeader() {

    var vScrollPanel = $("#mainContainer"),
        headerPanelContent = $("#headerPanelContent"),
        colHeaderPanelContent = $("#colHeaderPanelContent");

    var colHeaderPanelContent2 = document.getElementById('headerContent');

    colHeaderPanelContent2.style.top = (0 - vScrollPanel.scrollTop())+"px";

};

function scrollRowTableHeader() {

    var vScrollPanel = $("#mainContainer"),
        headerPanelContent = $("#headerPanelContent"),
        colHeaderPanel = $("#colHeaderPanel");

    var headerPanelContent2 = document.getElementById('headerPanelContent');

    headerPanelContent2.style.left = (0 - vScrollPanel.scrollLeft())+"px";

};
#container {
    /*background-color: green;*/
    display: flex;
}
.item {
    background-color: white;
    border: 1px solid black;
    flex-grow: 0;
}

.bigContent{
  height: 1000px;
  width: 1000px;
}

.scroll{
  overflow: auto;
  height: 300px;
  width: 500px;
}

.colheader{
  height: 300px;
  width: 200px;
  /*position: relative;*/
  z-index: 1;
  overflow:hidden;
  display: inline;
  border: solid 1px;
}

.headerContent{
  background: lightgrey;
  height: 1000px;
  width: 200px;
  position: relative;
  border: solid 1px;
}

.rowHeaderContent{
  background: whitesmoke;
  height: 100px;
  width: 200px;
  position: relative;
}

.rowColHeaderContent{
  background: lightyellow;
  height: 100px;
  width: 200px;
  border: solid 1px;
}

.headerPanel{
  overflow: hidden;
  width: 500px;
  border: solid 1px;
}

.tableProperties{
  table-layout: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="container">
  <div id="header" class="header">
    <div class="rowColHeaderContent">
        <table class="tableProperties">
          <tr><td>Row/Col Header</td></tr>
        </table> 
    </div>
  </div>
    <div id="headerPanel" class="headerPanel">
      <div id="headerPanelContent" class="rowHeaderContent">
         <table width="500px" class="tableProperties">
         <colgroup><col width="50"><col width="40"><col width="40"><col width="40"><col width="45"><col width="40"></colgroup>
            <tr><td>Some content (header)</td><td>Some content</td><td>Some content</td><td>Some content</td><td>Some content</td><td>Some content</td></tr>
         </table>
      </div>      
    </div>
</div>


<div id="container">
  <div id="colheader" class="colheader">
    <div id="headerContent" class="headerContent">
        <table width="500px" class="tableProperties">
          <tr><td>Column Header</td></tr>
          <tr><td>Column Header</td></tr>
          <tr><td>Column Header</td></tr>
          <tr><td>Column Header</td></tr>
          <tr><td>Column Header</td></tr>
          <tr><td>Column Header</td></tr>
        </table>
    </div>
  </div>
    <div id="mainContainer" class="item scroll">
      <div class="bigContent">
         <table width="500px" class="tableProperties">
         <colgroup><col width="50"><col width="40"><col width="40"><col width="40"><col width="45"><col width="40"></colgroup>
            <tr><td>Some content</td><td>Some content</td><td>Some content</td><td>Some content</td><td>Some content</td><td>Some content</td></tr>
         </table>
      </div>      
    </div>
</div>

【问题讨论】:

    标签: javascript css internet-explorer scroll


    【解决方案1】:

    所以,这不是对您的非常复杂问题的直接答案,但这里是..

    首先,您似乎正处于尝试创建固定列和固定行表的第一步。一开始它似乎可以工作,但是,相信我,你试图实现它的方式不会很好,原因是因为表格单元格的宽度是为 each 任意设置的表,您将无法将 header 表与其下方的 content 表对齐。因此,您要么必须采用与当前方式不同的方法 - 提示迫在眉睫。

    首先,在这种情况下大量数据的问题在 IE11 中更为明显——IE edge 的延迟较轻,而在其他浏览器中则没有延迟。在您的情况下,您可以使用 debounceing 来减少滚动时的 js 调用。

    setInterval(function(){                 
      // Scroll stuff here
    }, 2)
    

    间隔不必太高,轻微延迟是可见的,但与(我想)它目前的工作方式相比,这将是一个很大的改进。

    还可以尝试使用影响最小的 Javascript 函数,例如使用 .attr 而不是 .style;也可以尝试使用 CSS3 变换而不是普通变换。

    所以关于不同的方法 - 你必须以某种方式滚动标题和内容在同一个表中 - 理想情况下也是固定列。这里有一些提示。有必要使用 white-space:nowrap 删除表格单元格中的自动换行,以使以下提示按预期工作。这个概念可能很难理解,但一旦你遇到每个问题,它们就会变得有意义。

    首先在表格中添加一些顶部填充,以容纳接下来描述的标题元素。在标题单元格中创建pspan 元素,并将相同的标题内容放入它们中。使用 CSS3 变换将 span 元素绝对定位到顶部。

    “p”元素将保持静态,但不可见 - 使用 visibilityopacityheight:0 隐藏它们。如果th 内容超过td 内容,将使用段落元素。

    为了以良好的性能滚动所有内容,您必须在页面加载时缓存span 元素(小心:span 元素!)。

    希望这些提示对您有所帮助,如有任何问题,请随时提出 - 一开始可能很难消化,但会很有意义。

    【讨论】:

    • 谢谢你的答案。固定 cols 不是问题,我可以通过设置 table-layout fixed 和 来实现它(我已经更新了脚本)。固定行确实是一个问题。目前我有一个 JS 函数为左右表设置相同的高度(可能不是最佳实践,但它有效)。
    • IE/Edge 中滚动事件的问题是我得到的事件太少(因此 div 的移动有一点延迟),如果我使用 setInterval(...) 问题是强调。我会检查替代方法的提示,谢谢。
    • ...您所说的无效-实际上恰恰相反;实际上发生的事情是,当您滚动时,有太多事件,一个在另一个之上,浏览器引擎无法处理它,所以它会跳过帧。尝试我的解决方案并报告。我告诉你是因为我在类似的表格解决方案中遇到了同样的问题。
    • 我已经尝试过这种方式stackoverflow.com/questions/15591002/… 相信我,它更糟(在 Chrome 中也是如此)。左侧面板在更大的延迟后更新(这对我来说似乎是合理的)。我做错了什么?嗯……等一下……和你说的不完全一样……我再次检查一下对不起……
    • 这样? jsfiddle.net/Mich24/wsot9ar5(只需检查 JS 代码)。我可以确认情况更糟......
    【解决方案2】:
    • 如果你想只有右下窗格是可滚动的?

    • 我只是使用了类似的 css :-

      .headerContent{ 背景:浅灰色; 高度:1000px; 宽度:200px; 位置:静态; 边框:实心1px; }

    • 已更改position: relative into static...

    【讨论】:

    • 水平滚动时行列也要滚动,垂直滚动时列标题也要滚动
    猜你喜欢
    • 2014-12-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    相关资源
    最近更新 更多