Skip to content

Core Handler

This class is extended by all of our handlers, and has the purpose of handling all of the necessary logic to connect our handlers to our Manager.

constructor(payload) {
let { emitter, boostify, terraDebug, Manager, name } = payload;
this.boostify = boostify;
this.emitter = emitter;
this.name = name || "CoreHandler";
this.terraDebug = terraDebug;
this.Manager = Manager;
this.library;
this.libraryName;
this.boostifyConfig = {
distance: 10,
};
}

We will receive the name of the handler for debugging purposes, and all of the elements we need to work (boostify, our debugger and the Manager). Aside from this, we need to make a space for our library and our library name, which we will receive from our concrete handler.

For now, init() and events() are empty.

getLibraryName(name) {
this.libraryName = name;
}

This is the method we use to get the library name from our handler. This is the way our core handler will know which library it needs to import.

async assignInstances(payload) {
const { elementGroups } = payload;
if (elementGroups.length > 0) {
this.library = this.Manager.getLibrary(this.libraryName);
if (!this.library) {
await this.#retryLibrary();
}
elementGroups.forEach((configuration, index) => {
const { elements, config, boostify } = configuration;
elements.forEach((element) => {
if (
this.Manager.libraries.isElementInViewport({
el: element,
debug: this.terraDebug,
})
) {
this.createInstance({ element, config });
} else {
this.boostify.scroll({
distance: boostify ? boostify.distance : this.boostifyConfig.distance,
name: `${this.libraryName}-${index}`,
callback: async () => {
try {
this.createInstance({ element, config });
} catch (error) {
this.terraDebug && console.log("Error loading ", this.libraryName, error);
}
},
});
}
});
});
}
}

This is the function that will manage all the logic.

  1. First, it checks if the DOM elements are present to continue, if they are not, it does not perform any actions
  2. It gets the library from the Manager using the library name
  3. If the library is not imported yet, it retries until it gets it. This needs to be done to ensure the import has the time to occur before we go on to use it, as it is done asynchronally.
  4. It goes through the element groups and, for each of them, if the element is in the viewport, it creates the instance for it, and if it is not, it uses boostify to create the instance on scroll
createInstance({ element, config }) {
const Library = this.library;
// The configuration can be a callback if we need to access a concrete element
if (typeof config === "function") {
const conf = config(element);
this.Manager.addInstance(this.libraryName, new Library({ element, el: element, ...conf }));
} else {
this.Manager.addInstance(this.libraryName, new Library({ el: element, ...config }));
}
}

This function creates the instance and stores it in the manager.

It receives the library we imported in our assignInstances() method and uses the configuration we receive from our concrete handler.

If it is a function, it executes the function (here we have access to concrete elements because this function is invoked inside the foreach of the assignInstances() method). Once that is executed, the instance is added to the Manager.

If it is a plain object, we simply need to add the instance to the manager.

This logic allows us to connect our handlers with our Manager with a set of base functions that we do not need to worry about.

Knowledge Check

Test your understanding of this section

Loading questions...