I have a page where a scroll bar containing table rows with divs in them is dynamically generated from the database. Each table row acts like a link, sort of like you\'d see
You can also use the element.scrollIntoView()
options
el.scrollIntoView(
{
behavior: 'smooth',
block: 'start'
},
);
which most browsers support
For an element in a table row, use JQuery to get the row above the one you want, and simply scroll to that row instead.
Suppose I have multiple rows in a table, some of which should be reviewed by and admin. Each row requiring review has both and up and a down arrow to take you to the previous or next item for review.
Here's a complete example that should just run if you make a new HTML document in notepad and save it. There's extra code to detect the top and bottom of our items for review so we don't throw any errors.
<html>
<head>
<title>Scrolling Into View</title>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<style>
div.scroll { height: 6em; width: 20em; overflow: auto; }
thead th { position: sticky; top: -1px; background: #fff; }
.up, .down { cursor: pointer; }
.up:hover, .down:hover { color: blue; text-decoration:underline; }
</style>
</head>
<body>
<div class='scroll'>
<table border='1'>
<thead>
<tr>
<th>Review</th>
<th>Data</th>
</tr>
</thead>
<tbody>
<tr id='row_1'>
<th></th>
<td>Row 1 (OK)</td>
</tr>
<tr id='row_2'>
<th></th>
<td>Row 2 (OK)</td>
</tr>
<tr id='row_3'>
<th id='jump_1'><span class='up'>UP</span> <span class='down'>DN</span></th>
<td>Row 3 (REVIEW)</td>
</tr>
<tr id='row_4'>
<th></th>
<td>Row 4 (OK)</td>
</tr>
<tr id='row_5'>
<th id='jump_2'><span class='up'>UP</span> <span class='down'>DN</span></th>
<td>Row 5 (REVIEW)</td>
</tr>
<tr id='row_6'>
<th></th>
<td>Row 6 (OK)</td>
</tr>
<tr id='row_7'>
<th></th>
<td>Row 7 (OK)</td>
</tr>
<tr id='row_8'>
<th id='jump_3'><span class='up'>UP</span> <span class='down'>DN</span></th>
<td>Row 8 (REVIEW)</td>
</tr>
<tr id='row_9'>
<th></th>
<td>Row 9 (OK)</td>
</tr>
<tr id='row_10'>
<th></th>
<td>Row 10 (OK)</td>
</tr>
</tbody>
</table>
</div>
<script>
$(document).ready( function() {
$('.up').on('click', function() {
var id = parseInt($(this).parent().attr('id').split('_')[1]);
if (id>1) {
var row_id = $('#jump_' + (id - 1)).parent().attr('id').split('_')[1];
document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
} else {
alert('At first');
}
});
$('.down').on('click', function() {
var id = parseInt($(this).parent().attr('id').split('_')[1]);
if ($('#jump_' + (id + 1)).length) {
var row_id = $('#jump_' + (id + 1)).parent().attr('id').split('_')[1];
document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
} else {
alert('At last');
}
});
});
</script>
</body>
</html>
Building on an earlier answer, I am doing this in an Angular5 project.
Started with:
// el.scrollIntoView(true);
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
window.scrollBy(0, -10);
But this gave some problems and needed to setTimeout for the scrollBy() like this:
//window.scrollBy(0,-10);
setTimeout(() => {
window.scrollBy(0,-10)
}, 500);
And it works perfectly in MSIE11 and Chrome 68+. I have not tested in FF. 500ms was the shortest delay I would venture. Going lower sometimes failed as the smooth scroll had not yet completed. Adjust as required for your own project.
+1 to Fred727 for this simple but effective solution.
Simple solution for scrolling specific element down
const element = document.getElementById("element-with-scroll");
element.scrollTop = element.scrollHeight - 10;
If it's about 10px, then I guess you could simply manually adjust the containing div
's scroll offset like that:
el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop -= 10;
My main idea is creating a tempDiv above the view which we want to scroll to. It work well without lagging in my project.
scrollToView = (element, offset) => {
var rect = element.getBoundingClientRect();
var targetY = rect.y + window.scrollY - offset;
var tempDiv;
tempDiv = document.getElementById("tempDiv");
if (tempDiv) {
tempDiv.style.top = targetY + "px";
} else {
tempDiv = document.createElement('div');
tempDiv.id = "tempDiv";
tempDiv.style.background = "#F00";
tempDiv.style.width = "10px";
tempDiv.style.height = "10px";
tempDiv.style.position = "absolute";
tempDiv.style.top = targetY + "px";
document.body.appendChild(tempDiv);
}
tempDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
Example using
onContactUsClick = () => {
this.scrollToView(document.getElementById("contact-us"), 48);
}
Hope it help