I'm making a simple file viewer in Tauri framework (Just simple HTML and CSS). Because of long files I can't just put the content of the file to the <pre>
element that I use to display the visible lines. So I call the rust backend with parameters of what lines are visible inside of a viewport to render just those. To simulate the scrolling i use <div>
scaled to math the size that will the text have if will be displayed normally in one piece. While the <pre>
is fixed to the viewport and can't be moved with.
Now when i scroll on one axis I'm unable to scroll on the other unless i wait a couple of seconds. This bug gives me no errors in the debugging console.
Code in charge of updating the lines:
addEventListener("scroll", () => {
if (last_number_of_lines_above_viewport !== get_lines_above_viewport()) {
lazy_redraw();
last_number_of_lines_above_viewport = get_lines_above_viewport();
}
});
function lazy_redraw() {
if (loaded_file) { //Catches no file was loaded
invoke('lazy_read_lines', {file_path: loaded_file.file_path, filter: filtered_tab_lines.slice(get_lines_above_viewport(), get_lines_above_viewport() + get_lines_inside_viewport())})
.then((message) => { //Just returns string of lines inside a specified viewport
document.getElementsByClassName("file")[0].innerText = message;
}
);
}
}
<pre>
element css style:
.file {
margin: 0px;
position: fixed;
top: 25px;
left: 0;
height: 100%;
width: 100%;
overflow-x: auto;
overflow-y: hidden; /* Sometimes one line is slightly below the viewport, causing an extra scrollbar */
}
I thought the problem is caused by different lines length but after putting spaces at the end of the shorter ones to make their length equal i don't get any difference.
I have also tried updateing the viewport using the requestAnimationFrame()
:
let animationFrameId = null;
addEventListener("scroll", () => {
if (animationFrameId === null) {
animationFrameId = requestAnimationFrame(scrollHandler);
}
});
function scrollHandler() {
if (last_number_of_lines_above_viewport !== get_lines_above_viewport()) {
lazy_redraw();
last_number_of_lines_above_viewport = get_lines_above_viewport();
}
animationFrameId = requestAnimationFrame(scrollHandler);
}
As it turned out, the problem was that the <pre>
element that displays the text lost focus when user clicked outside, than the browser didn't listen to scrolling on that element until I click back in it.
I fixed it by returning focus to that element when lost, I know that this solution isn't optimal but it works fine in my case.
<pre onfocusout="document.getElementById('file').focus();" id="file" autofocus></pre>