I am making a rather complex website that has as a key factor texts in different panels that I want to make scroll together (synchronously). That is: when the user scrolls down a few lines in one panel, the other panel presenting a parallel text should scroll the same few lines. Further, at the top of each panel I have an information line, saying just what text the panel contains. I want this to stay in view and not scroll out of sight, while the text below in the panel scrolls.
I can do one thing, but not the other. I have made a jSFiddle that shows my attempts to make this work at JS Fiddle. Here is a key bit of the code:
let thisLine=$(scrollMe[0]).find("p[n='"+nVal+"']")[0]
thisLine.scrollIntoView();
The whole file is available at www.inklesseditions.com/TCR/testsyncscroll.html. Thus:
Help! I've been stuck for ages on this. It appears that in the bottom panel scrolling in one window causes some kind of race condition, which does not end until both panels have scrolled to the very bottom.
I'm aware that scrolling is really tricky, with different combinations of "overflow auto/scroll/hidden" etc and different height settings causing unpredictable behaviour. I am sure that some combination exists that will do what I want. I just don't know what it is.
I've included in my code elements outside this particular problem. I did that because I use flexbox throughout and it's possible that there is some interaction with flexbox which is causing this misbehaviour.
I figured out the exact problem and how to fix it. The problem was that the synchronous scroll function sent an update message to a panel which triggered a scroll event in that target panel,which called the sychronous scroll function, which then went then sent another update, and on for ever. The solution was:
The core code is this:
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();
}
This is in a JSFiddle at https://jsfiddle.net/peterrr73/83beksng/5/.
A slight wrinkle: I added a few lines to catch cases where the scroll had already been done. Not sure if this is a problem with scrollend. Anyway, works well. Scroll any one of the five panels and the others all move in harmony.