使用HTML和CSS制作的时间线内滚动。

4

我正在开发一个网站项目,需要绘制一条时间轴,其中包含行和信息(类似于甘特图)。基本上以下几点很重要:

  • 用户可以在时间轴上向左或向右滚动。
  • 时间轴可以在垂直方向上滚动(浏览行)。
  • 行的名称始终显示在行本身上。

为了澄清事情,我创建了以下杰作艺术timeline

我们可以看到红色的时间轴和行,行名在左侧(橙色),行上的条目为蓝色。因此,将时间轴向右滚动会产生以下结果:

timeline scrolled

这些名称仍然位于同一位置,正如我们所看到的,这恰恰是我要问的问题:
在水平和垂直可滚动的容器中保持项目在同一水平位置的最佳实践是什么?当通过行进行垂直滚动时,橙色块也应该随之滚动。
但是!你到底尝试了什么?
我尝试了一些方法,但没有找到完美的解决方案:
1)更改左侧属性
我尝试使用JavaScript更改橙色块的CSS“left”属性,在水平移动时(使用Translate()改变位置没有改变太多)。这在Chrome上效果很好,但在IE上(我仍然不明白为什么人们使用它),它非常缓慢,并且位置更新明显可见。如果您拿起滚动条并疯狂滚动,您可以看到橙色框从左到右飞行。这使我想到了以下想法:
2)你!出去!
我为橙色方框创建了一个单独的容器元素,并将其放置在时间轴外部,给它设置了绝对位置并放置在时间轴顶部,这样无论用户是否滚动时间轴,它都会保持在那里。结果:外观没有任何变化,左右滚动完美运作,因为我不必设置橙色方框的左侧位置。但是...该解决方案可能适用于水平滚动,但在垂直滚动时,橙色方框不知道时间轴的垂直位置,因此该解决方案的缺点包括:

  • 必须使用JavaScript设置橙色方框的垂直滚动位置。
  • 在IE上垂直滚动有些卡顿(但比第一种解决方案更流畅和不那么烦人)。
  • (次要)两个容器的高度必须相同,这意味着需要设置高度(如果需要)必须进行两次。

我希望您能够帮助我!


FYI:这种做法通常被称为“冻结”列。这可能有助于您的研究工作。 - esqew
我完全理解你想要一些代码的原因,但这是不可能的,因为1)该项目是我所在公司的项目。2)页面上使用的HTML、CSS和JavaScript非常庞大,到处都有(knockoutjs)绑定,并且时间轴连接到内部服务,因此显示真实数据。这就是为什么我尽力创建了一个非常简化的相关核心版本的图纸。 - Memet Olsen
2
实际上,我正在寻求实现我所描述的最佳方法。因此,提供我不满意的代码似乎有点奇怪。我已经尝试了解决方案1和2,我需要第三个解决方案。 - Memet Olsen
假设您在方案2中所说的是“fixed”定位,也许您可以在垂直滚动时将其切换为“absolute”,这样它就会自然地滚动而不是通过JavaScript。然后当它停止滚动时,重置为“fixed”,并记录并设置每个框的“top”定位? - Ross Joo
回复:你是如何生成页面的?重复迭代行有什么问题吗? - Basic
显示剩余3条评论
2个回答

1

我不认为这正是你想要的,但我还是想发布一下,因为它与你的解决方案2有些不同,可能有一些优势。

http://codepen.io/anon/pen/qsfGJ

<div class="container">
<div class="right-column">
    <div class="left-column">
        <div class="label">Label 1</div>
        <div class="label">Label 2</div>
        <div class="label">Label 3</div>
        <div class="label">Label 4</div>
        <div class="label">Label 5</div>
        <div class="label">Label 6</div>
        <div class="label">Label 7</div>
        <div class="label">Label 8</div>
        <div class="label">Label 9</div>
        <div class="label">Label 10</div>
        <div class="label">Label 11</div>
        <div class="label">Label 12</div>
        <div class="label">Label 13</div>
        <div class="label">Label 14</div>
    </div>
    <div class="row">
        <div class="row-label">Row 1</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 2</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 3</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 4</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 5</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 6</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 7</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 8</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 9</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 10</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 11</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 12</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 13</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
    <div class="row">
        <div class="row-label">Row 14</div>
        <div class="event"></div>
        <div class="event"></div>
    </div>
</div>
</div>

1

可滚动的水平时间轴 - CSS3

最近我在处理类似问题时,偶然发现了这个(相当古老的)问题,即使IE已经“退出了舞台”,但仍然觉得这个任务相对具有挑战性。以下是我的解决方案,使用 position: sticky;

示例 - 带有额外的标尺和条形图:

.TL {
  font: 14px/1.4 sans-serif;
  position: relative;
  height: 100px; /* set as desired */
  overflow: scroll;
  background: #ddd;
}
.TL-scroll {
  width: max-content;
  min-width: 100%;
}
.TL-row {
  display: flex;
  flex-flow: row nowrap;
  border-bottom: 1px solid #aaa;
  flex: none;
  min-width: 100%;
}
.TL-row--top {
  background: #eee;
  position: sticky;
  top: 0;
  z-index: 3;
}
.TL-row--top .TL-rowCells {
  background-image:
    repeating-linear-gradient(90deg, #aaa, #aaa 1px, transparent 1px, transparent 100px),
    repeating-linear-gradient(90deg, #aaa, #aaa 1px, transparent 1px, transparent 10px);
  background-repeat: no-repeat, no-repeat;
  background-position: 0 6px, 0 14px;
}
.TL-rowName {
  position: sticky;
  flex: 0 0 120px;
  z-index: 2;
  left: 0;
  width: 200px;
  padding: 10px;
  background: #eee;
}
.TL-rowRuler {
  z-index: 1;
  width: 1px;
  background: #f0a;
  /* IMPORTANT use translateX to move the rulers! */
  transform: translateX(161px); /* This will most probably be handled by JS */
}
.TL-rowCells {
  position: relative;
  display: flex;
  width: 100%;
  flex-flow: row nowrap;
}
.TL-cell {
  padding: 10px 0;
  background: #0cf;
  border-right: 1px solid #eee;
  text-align: center;
}
<div class="TL">

  <div class="TL-scroll">

    <div class="TL-row TL-row--top">
      <div class="TL-rowName"></div>
      <div class="TL-rowRuler"></div>
      <div class="TL-rowCells"></div>
    </div>

    <div class="TL-row">
      <div class="TL-rowName">1 Row name</div>
      <div class="TL-rowRuler"></div>
      <div class="TL-rowCells">
        <div class="TL-cell" style="width:50px; margin-left:0px;">50</div>
        <div class="TL-cell" style="width:120px; margin-left:40px;">120</div>
        <div class="TL-cell" style="width:190px; margin-left:400px;">190</div>
      </div>
    </div>

    <div class="TL-row">
      <div class="TL-rowName">Row 2</div>
      <div class="TL-rowRuler"></div>
      <div class="TL-rowCells">
        <div class="TL-cell" style="width:300px; margin-left:20px;">300</div>
        <div class="TL-cell" style="width:20px; margin-left:100px;">20</div>
        <div class="TL-cell" style="width:60px; margin-left:5px;">60</div>
        <div class="TL-cell" style="width:100px; margin-left:40px;">100</div>
        <div class="TL-cell" style="width:80px; margin-left:0px;">80</div>
        <div class="TL-cell" style="width:30px; margin-left:50px;">30</div>
        <div class="TL-cell" style="width:60px; margin-left:0px;">60</div>
      </div>
    </div>

    <div class="TL-row">
      <div class="TL-rowName">Row 3 name</div>
      <div class="TL-rowRuler"></div>
      <div class="TL-rowCells">
        <div class="TL-cell" style="width:200px; margin-left:300px;">200</div>
        <div class="TL-cell" style="width:40px; margin-left:20px;">40</div>
      </div>
    </div>

  </div>

</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接