Reputation: 10589
I have a list of charts. I use Chart.js to create those charts. Since my list can have 1 to 100 or more entries initializing all charts at once would not be smart because that would make the ui freeze for a long time. So instead I thought it would be much better to only initialize those charts which are visible inside the view bounds of the browser so that for example only the first chart is getting initialized and when the user scrolls down and the second canvas becomes visible the second is getting initialized and so on.
I have everything setup but the only problem that I have right now is: how can I create an eventlistener or anything similiar which I can add to each canvas element that gets triggered when a canvas becomes visible inside the view bounds of the browser so that i can perform the chart initialization for that canvas?
Upvotes: 1
Views: 2926
Reputation: 21
I usually draw some stuff; canvas is an example. Clean JS.Here, you can read a lot more about how it works. https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
const canvases = document.querySelectorAll("canvas");
canvases.forEach( (canvas) => {
var options = {
threshold: 0.01,
};
var canvas_observer = new IntersectionObserver((entries, observer) => {
// Loop through the entries
for (const entry of entries) {
// Check if the entry is intersecting the viewport
if (entry.isIntersecting) {
console.log("Intersected")
}
else{
console.log("Exit")
}
}
}, options);
canvas_observer.observe(canvas);})
Upvotes: 0
Reputation: 445
I'm the author of OnScreen, a small library that can call a callback function when a HTMLElement
enters the viewport or the boundaries of its container.
// Uses ES6 syntax
import OnScreen from 'onscreen';
const os = new OnScreen();
os.on('enter', 'canvas', (element) => {
if (!element.chartInitialized) {
// Initialize the chart
// Update the `chartInitialized` property
// to avoid initializing it over and over
element.chartInitialized = true;
}
});
For more information, take a look at the documentation. Don't forget to check the demos repo for a couple simple examples.
Upvotes: 1
Reputation: 2263
I have used the onScreen jQuery plugin.
It is very easy. You just have to call for each canvas this:
$('elements').onScreen({
container: window,
direction: 'vertical',
doIn: function() {
// initialize canvas
},
doOut: function() {
// Do something to the matched elements as they get off scren
},
tolerance: 0,
throttle: 50,
toggleClass: 'onScreen',
lazyAttr: null,
lazyPlaceholder: 'someImage.jpg',
debug: false
});
Upvotes: 1