我正在制作一个相当复杂的网站,它的关键因素是不同面板中的文本,我想让它们一起滚动(同步)。也就是说:当用户在一个面板中向下滚动几行时,呈现并行文本的另一个面板应该滚动相同的几行。此外,在每个面板的顶部都有一个信息行,说明面板包含的文本。我希望它保持在视图中,并且不会滚动到视线之外,而面板中下面的文本会滚动。
我可以做一件事,但不能做另一件事。我制作了一个 jSFiddle 来展示我在 JS Fiddle 上进行这项工作的尝试。这是代码的关键部分:
let thisLine=$(scrollMe[0]).find("p[n='"+nVal+"']")[0]
thisLine.scrollIntoView();
整个文件可在 www.inklesseditions.com/TCR/testsyncscroll.html 获取。因此:
救命!我在这件事上被困了好久了。看来在底部面板中在一个窗口中滚动会导致某种竞争条件,直到两个面板都滚动到最底部时才会结束。
我知道滚动确实很棘手,“溢出自动/滚动/隐藏”等的不同组合和不同的高度设置会导致不可预测的行为。我确信存在某种组合可以实现我想要的功能。我只是不知道那是什么。
我已经在我的代码中包含了这个特定问题之外的元素。我这样做是因为我自始至终都使用 Flexbox,并且可能与 Flexbox 存在一些交互,从而导致了这种不当行为。
我找出了确切的问题以及如何解决它。问题在于,同步滚动函数向面板发送了一条更新消息,该消息触发了该目标面板中的滚动事件,该事件调用了同步滚动函数,然后发送了另一个更新,并永远持续下去。解决方案是:
核心代码是这样的:
function scrollPanel(targetPanel, scrollMe){
targetPanel.off("scroll"); //turn off call to sync function
targetPanel.addEventListener("scrollend", (event) => {
targetPanel.on("scroll", cfScroll); //turn it back on after scroll
});
targetPanel[scrollMe].scrollIntoView();
}
这是在 JSFiddle 中:https://jsfiddle.net/peterrr73/83beksng/5/。
一个小问题:我添加了几行来捕捉已经完成滚动的情况。不确定这是否是scrollend 的问题。无论如何,效果很好。滚动五个面板中的任何一个,其他面板都会和谐移动。