Reputation: 2324
I am having trouble getting scrollIntoView API working correctly when there are lazy image load on the page.
Essentially, when the page loads, I grab the element via querySelector
and when it scrolls, the focus is off due to the image loading (it shifts the pages down).
I've tried pages without lazy image load and it worked fine as expected.
I am not entirely how I can go on about this.
Upvotes: 2
Views: 2549
Reputation: 1446
I have the same problem, and I have two workarounds. Neither are super ideal but they do work.
There are a few concepts you can try, one of which is to poll for the scrolling event to finish, but if you use durations you should be able to guesstimate the whole thing. Using the default swing easings will make the animation slow down and speed up halfway so you are kind of stuck with using linear.
The idea for this then is to launch the scrolling animation, and just before it ends, launch another scrolling animation. The first should get you approximately where you want to go, and near the end of it, the document should have loaded whatever it needed to in between and the second animation should then narrow it down and scroll to the correct spot.
The main animation and the patch animation need to overlap. I have set them so that the patch animation will complete at the same time as the main animation. This is probably bad form. You can try to start the patch when the main animation ends, or so that it extends past the finish of the main animation. Tune the numbers to get the results you want.
This is, of course, hackery.
With jQuery you can get a callback for the completion of the animation and that is maybe a better approach than running the two at the same time.
First with jQuery using setTimeout to guess the time to start patching:
$(function() {
$('html,body').animate({ // main animation block
scrollTop: target.offset().top
},{
easing: 'linear',
duration: 800 // how long to animate in total
});
setTimeout(function() {
$('html,body').animate({
scrollTop: target.offset().top
}, {
easing: 'linear',
duration: 200 // how long to patch the animation
});
},600); // how long to wait before starting the patch
});
Second with jQuery using the complete, this is cleaner:
$(function() {
$('html,body').animate({
scrollTop: target.offset().top
},{
duration: 600, // main animation time
easing: 'linear',
complete: function() {
$('html,body').animate({
scrollTop: target.offset().top,
},{
easing: 'linear',
duration: 200 // patch time, this starts after main
});
}
});
});
Safari does not support out of the box smooth scrolling so needs jQuery or some other javascript library to do it. The following should work though for Chrome, Edge, Firefox, etc:
var source = document.getElementById('yoursourceelementid');
source.onclick = function() {
var target = document.getElementById('idyouwanttoscrollto');
target.scrollIntoView({
behavior: 'smooth',
block: 'start',
duration: 800 // how long to animate
});
setTimeout(function() { // patch animation
target.scrollIntoView({
behavior: 'smooth',
block: 'start',
duration: 200 // how long to patch
});
}, 600); // how long to wait before patching
}
Upvotes: 1