冻结标题直到不相关(HTML、CSS 和 JS)

发布于 2024-12-04 14:31:39 字数 449 浏览 0 评论 0原文

我有几个不同的表格,我想在页面上垂直显示它们。问题是,不同的表有不同的列标题。

图中,深色边框代表视口。红色虚线边框是红色标题所属的位置,但请注意,它“冻结”到视口的顶部。一直如此,直到在第二张图片中,绿色标题开始取代它。 http://imagebin.org/172108Concept Picture

有谁知道如何使用非常轻量级的脚本(换句话说,我不需要 JQuery 或其他东西)和 CSS 来实现这一点。我的优点是我只需要它在 Webkit 上渲染(这意味着一些 css3 也是一个选项)。我不在乎标题是否实际上不是 html 的一部分 - 但它们显然必须正确排列。

I have a few different tables that I want to display vertically down a page. The trouble is, the different tables have different column headings.

In the picture, the dark border represents the viewport. The dotted red border is where the red header belongs but note that it is "frozen" to the top of the viewport. This is true until, in the second image, the green header begins to replace it.
http://imagebin.org/172108Concept Picture

Does anyone know how this could be accomplished using very lightweight scripting (In other words, I don't want JQuery or something) and CSS. I have the advantage that I only need it to render on Webkit (which means some css3 is also an option). I don't care if the headers are not actually part of the html <table> - they must obviously just line up properly though.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

人│生佛魔见 2024-12-11 14:31:40

使用 position:sticky 可以在纯 CSS 中实现结果

It's possible to achieve the result in pure CSS with position:sticky ????

body, dl, dt, dd {
  margin: 0;
}
dl {
  position: relative;
}
dt, dd {
  padding: 1rem;
}
dt {
  background-color: #ddd;
  position: sticky;
  top: 0;
  box-shadow: 0 0 0.25rem rgb(0 0 0 /10%);
}

I got a pen 4 years ago. You can jump in to see how it works:
https://codepen.io/patrickliu/full/MGPNgJ

迷乱花海 2024-12-11 14:31:39

编辑: http://jsfiddle.net/BCtP8/3/

在那里,我修复了打嗝的文本。当标题固定后,我更改占位符的高度。我还更改了它以适用于任何标题高度,而不仅仅是我给他们的标题高度。

旧帖子
在这里,伙计:

http://jsfiddle.net/BCtP8/

对于可能出现的任何问题,我深感抱歉,我我对整个网络开发场景相当陌生,我没有经验来预测可能会发生什么。

我怀疑这是最好或最有效的方法,所以如果您找到更好的方法,请将其发布在这里,以便我可以学习。谢谢。

edit: http://jsfiddle.net/BCtP8/3/

There, I fixed the hiccuping text. When the header becomes fixed, I change the placholder's height. I also changed it to work with any header height, not just the one I had given them.

OLD POST
Here you go man:

http://jsfiddle.net/BCtP8/

Sorry for any problems that might occur, I'm quite new to the whole web developing scene and I don't have the experience to predict what might happen.

I doubt this is the best or most efficient way to do it, so if you find better, please post it here so I can learn. Thanks.

梦冥 2024-12-11 14:31:39

这只能通过 Javascript 实现——我想不出一种简单地使用 CSS 来做到这一点的方法。

答案的基础是在元素上使用 position:fixed 。我建议克隆表格的 thead 并将其附加到表格顶部的固定位置,然后为 scroll 事件添加事件侦听器并检查位置每个表相对于已滚动的金额。

我在 JSFiddle 上放置了一个 示例

This will only be possible with Javascript - I can't think of a way of doing it simply with CSS.

The basis of the answer is to use position:fixed on the element. I would suggest cloning the thead of your table to attach in a fixed position at the top of the table, and then add an event listener for the scroll event and check the position of each table against the amount that has been scrolled.

I've put up an example on JSFiddle.

最舍不得你 2024-12-11 14:31:39

其价值在于:

这里有几个答案,但我认为它们实际上并没有回答这个问题。它们不对表头(thead 元素)进行操作,或者使用第 3 方库。将 thead 移出表格会出现一些微妙的问题 - 其中最大的问题是,如果标题文本比 tbody< 中的数据更宽或更窄,单元格就会折叠起来。 /代码>。

这是我的解决方案,它可以解决问题,无需任何库并处理表头。它不对表格的样式或标题的大小做出任何假设;一切都是经过计算的。仅根据 OP 的要求在 Chrome 中进行测试。

脚本:

function initFloatingHeaders() {
  var tables = document.querySelectorAll('table.float-header');
  var i = tables.length;

  while (i--) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'floating-header';
    var clone = table.cloneNode(true);
    wrapper.appendChild(clone);
    table.parentNode.insertBefore(wrapper, table);

    var thead = table.querySelector('thead');
    wrapper.style.width = thead.scrollWidth + 'px';  
    wrapper.style.height = thead.scrollHeight + 'px';
    wrapper.style.left = table.offsetLeft + 'px';     
  }

  window.addEventListener('scroll', function() {
    var headers = document.querySelectorAll('div.floating-header');
    var bodyHeight = document.body.offsetHeight;
    var i = headers.length;
    while (i--) {
      var header = headers[i];
      var tableBounds = header.nextSibling.getBoundingClientRect();
      if (tableBounds.top < 0 && tableBounds.bottom > 0) {
        header.style.display = 'block';
      } else {
        header.style.display = null;
      }
    }
  }, false);
}

表格应应用 float-header 类,并且应在加载或 documentReady 时调用 initFloatingHeaders。示例:http://jsbin.com/ulusit/2(过渡效果不佳的旧示例:http://jsbin.com/ulusit/)

For what it's worth:

There are a couple of answers here but I don't think they actually answer the question. They don't operate on table headers (thead elements) or they use 3rd party libraries. There are some subtle issues with lifting a thead out of the table - the largest of which is that the cells will collapse down if the header text is wider or narrower than the data in the tbody.

Here is my solution that solves the problem without any libraries and working on table headers. It makes no assumptions about the styling of the table, or the size of the headers; everything is calculated. Only tested in Chrome per the requirements of the OP.

Script:

function initFloatingHeaders() {
  var tables = document.querySelectorAll('table.float-header');
  var i = tables.length;

  while (i--) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'floating-header';
    var clone = table.cloneNode(true);
    wrapper.appendChild(clone);
    table.parentNode.insertBefore(wrapper, table);

    var thead = table.querySelector('thead');
    wrapper.style.width = thead.scrollWidth + 'px';  
    wrapper.style.height = thead.scrollHeight + 'px';
    wrapper.style.left = table.offsetLeft + 'px';     
  }

  window.addEventListener('scroll', function() {
    var headers = document.querySelectorAll('div.floating-header');
    var bodyHeight = document.body.offsetHeight;
    var i = headers.length;
    while (i--) {
      var header = headers[i];
      var tableBounds = header.nextSibling.getBoundingClientRect();
      if (tableBounds.top < 0 && tableBounds.bottom > 0) {
        header.style.display = 'block';
      } else {
        header.style.display = null;
      }
    }
  }, false);
}

Tables should have the class float-header applied and initFloatingHeaders should be called on load or documentReady. Example: http://jsbin.com/ulusit/2 (Old example with bad transitions: http://jsbin.com/ulusit/)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文