在div内滚动div并使面板同步滚动时出现scrollIntoView问题

问题描述 投票:0回答:1

我正在制作一个相当复杂的网站,它的关键因素是不同面板中的文本,我想让它们一起滚动(同步)。也就是说:当用户在一个面板中向下滚动几行时,呈现并行文本的另一个面板应该滚动相同的几行。此外,在每个面板的顶部都有一个信息行,说明面板包含的文本。我希望它保持在视图中,并且不会滚动到视线之外,而面板中下面的文本会滚动。

我可以做一件事,但不能做另一件事。我制作了一个 jSFiddle 来展示我在 JS Fiddle 上进行这项工作的尝试。这是代码的关键部分:

let thisLine=$(scrollMe[0]).find("p[n='"+nVal+"']")[0]
thisLine.scrollIntoView();

整个文件可在 www.inklesseditions.com/TCR/testsyncscroll.html 获取。因此:

  1. 如果滚动所有四个面板:您将看到底部的面板正确滚动。也就是说:当下面的文本滚动时,文本“文本滚动时保持在顶部”保留在那里。顶部的面板无法正确滚动:当下面的文本滚动时,文本“随文本滚动”会滚动到视线之外。
  2. 单击“同步滚动”教科书,现在它已被选中。滚动顶部两个面板之一中的文本。它运作良好:当您滚动任一面板时,两个面板中的文本都会一起移动。但底部两个面板中的文本无法正确滚动。相反,它始终滚动到每个面板中文本的最底部,即使您只想向任一方向滚动一行。此外,“文本滚动时保持在顶部”这一行会滚动到视线之外。

救命!我在这件事上被困了好久了。看来在底部面板中在一个窗口中滚动会导致某种竞争条件,直到两个面板都滚动到最底部时才会结束。

我知道滚动确实很棘手,“溢出自动/滚动/隐藏”等的不同组合和不同的高度设置会导致不可预测的行为。我确信存在某种组合可以实现我想要的功能。我只是不知道那是什么。

我已经在我的代码中包含了这个特定问题之外的元素。我这样做是因为我自始至终都使用 Flexbox,并且可能与 Flexbox 存在一些交互,从而导致了这种不当行为。

javascript panel synchronous custom-scrolling
1个回答
0
投票

我找出了确切的问题以及如何解决它。问题在于,同步滚动函数向面板发送了一条更新消息,该消息触发了该目标面板中的滚动事件,该事件调用了同步滚动函数,然后发送了另一个更新,并永远持续下去。解决方案是:

  1. 在发送更新之前禁用对目标面板上同步滚动功能的调用
  2. 将(相对)新的“scrollend”事件附加到目标面板,这样当它完成响应更新时,同步滚动功能将在面板完成滚动后重新启用

核心代码是这样的:

 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的问题。

© www.soinside.com 2019 - 2024. All rights reserved.