Exploring Vue 3: A guide to sending an array of items to a directive

As I couldn't find an existing IntersectionObserver library for Vue 3, I am planning to create my own custom solution.

After researching about directives, it seems like the right approach. (?)

This is my local directive:

directives: {
    'lazyload': {
      mounted(el) {
        if ('IntersectionObserver' in window) {        
          let intersectionObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry) => {
              if (entry.isIntersecting) {
                const lazyImage = entry.target;
                
                // set data-srcset as image srcset
                lazyImage.srcset = lazyImage.getAttribute('data-srcset');
                
                // add class after image has loaded
                lazyImage.addEventListener('load', () => {
                  lazyImage.classList.add('is-lazyloaded');
                });
                // unobserve after
                lazyLoadItemObserver.unobserve(lazyImage);
              }
            });
          });
          
          // observe every image
          const lazyLoadItems = document.querySelectorAll('[lazyload]')
          
          lazyLoadItems.forEach((lazyImage) => {
            lazyLoadItemObserver.observe(lazyImage);
          });
  
        }
      }
    }
  }

The traditional method would involve creating an array of all <IMG> elements with the attribute lazyload, for example. However, I'm unsure how to create such an array for <IMG> elements with the v-lazyload binding.

I want a directive that establishes a single IntersectionObserver observing an array of images with the v-lazyload binding.

Answer №1

When using the v-lazyload directive, there is no need to query the document as it will already be on the target elements.

To implement this functionality, in the mounted hook of the directive, an IntersectionObserver instance can be attached to the parent node if one does not already exist. This instance can then be used to observe the target element and unobserve it in the unmounted hook:

directives: {
  mounted(el) {
    el.parentNode.lazyLoadItemObserver = el.parentNode.lazyLoadItemObserver || new IntersectionObserver(/*...*/)
    el.parentNode.lazyLoadItemObserver.observe(el)
  },
  unmounted(el) {
    el.parentNode.lazyLoadItemObserver.unobserve(el)
  },
}

Check out a demo of this implementation here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying the fields of the selected [object Object] in the console.log

Currently, I am utilizing "express": "3.2.6",, nodeJS v0.10.25, and "express-myconnection": "1.0.4",. The database connection appears to be functioning properly. However, when attempting to query in my view: console.log("Data: " + rows); The output rece ...

Having Trouble with Shopify's Asynchronous Ajax Add to Cart Feature?

I have developed a unique Shopify page design that allows users to add multiple items to their cart using Shopify's Ajax API. I've created a test version of the page for demonstration: Below is the current javascript code I am using to enable as ...

JavaScript data manipulation: Determining percentage change within a nested JSON structure

Provided is a JSON file structured like this... data =[ { key: "london", values: [ {day: "2020-01-01", city: "london", value: 10}, {day: "2020-01-02", city: "london", value: 20}, {day: " ...

What could be the reason for the malfunction of jQuery's show() function?

Using jQuery, I have implemented a functionality to hide a div using the hide() method. However, upon clicking a link, the div is supposed to show but unexpectedly disappears after appearing briefly. HTML Code Snippet <div id="introContent"> & ...

Mistakes in Compiling Typescript Code in Angular 2

Currently, I am utilizing Visual Studio 2017 for the development of an Angular 2 application with an Asp.Net Core WebApi backend. My guide through this process is the ASP.NET Core and Angular 2 Book authored by Valerio De Sanctis. Initially, everything was ...

When utilizing bootstrap, encasing an input text element in a label results in the text becoming bold and not occupying the entire width

I have been experimenting with wrapping my text input fields in labels. While this technique works well with pickers on my form, it seems to cause issues when applied to text boxes. If I choose not to wrap the text boxes, the alignment between the label an ...

The functionality of Angular 2's AsyncPipe seems to be limited when working with an Observable

Encountering an Error: EXCEPTION: Unable to find a support object '[object Object]' in [files | async in Images@1:9] Here's the relevant part of the code snippet: <img *ngFor="#file of files | async" [src]="file.path"> Shown is the ...

The main source for loading the 'XYZComponent' cannot be located

There's an issue I'm facing where ng2 code is being loaded into a .Net MVC component, but the console is showing the following error: EXCEPTION: Uncaught (in promise): Error: Cannot find primary outlet to load 'UsersComponent' Error: C ...

How can we ensure that pointer events return the same coordinates as touch events when the viewport is zoomed in?

I attempted to utilize pointer events (such as pointerdown) instead of using a combination of touch events (e.g. touchstart) and mouse events (e.g. mousedown) to determine the input event coordinates. var bodyElement = document.body; bodyElement.addEvent ...

Curious about learning the Xpath?

This is the HTML content <dd id="_offers2" itemprop="offers" itemscope="" itemtype="http://schema.org/Offer" class="wholesale nowrap "> <span itemprop="price" class="Hover Hover Hover">$46.29</span> / each <meta itempr ...

What is the best way to trigger a unique modal dialog for every element that is clicked on?

I simply want to click on the state and have that state's specific pop-up appear. $("path, circle").on('click', function(e) { $('#info-box').css('display', 'block'); $('#info-box').html($(this ...

Passing an event from Electron's IPC renderer to Vuex

Greetings, fellow developers! I'm currently working on an app that involves multiple windows. My App is built using Vue + Electron technology stack. One of the key features I am trying to implement is triggering actions in Electron to open a popup, fo ...

elementToBeClickable is not supported by webdriverio

I am having some trouble with the 'waitForEnabled' function as it does not seem to behave like Webdriver's elementToBeClickable. Is there anyone who can provide some guidance on how to use this API effectively? ...

Display additional input field using Jquery when text is entered in the textbox

Is there a way to display the input field #f_past_data when the text field #f_past_farmaco is filled out? The field #f_past_farmaco is for entering text. I attempted the following solution but it did not work as expected. $('label[for=f_past_data], ...

How can you reposition a component within the dom using Angular?

Just started learning Angular, so I'm hoping this question is simple :) Without getting too specific with code, I could use some guidance to point me in the right direction. I'm currently developing a small shopping list application. The idea i ...

The function that iterates through the 'categoria' state and returns a new array is not functioning properly

Having difficulty with the object of a function using .map(). It works when the code is used directly, but not when put inside a function. For example: if(this.state.cat){ return _.map(this.state.cat, categoria => { if(this.state.search_ ...

Listen for the 'open' event on a node HTTP server

This question pertains to a previous inquiry I had about node httpServer encountering the EADDRINUSE error and moving to the next available port. Currently, my code looks like this: var port = 8000; HTTPserver .listen(port, function() { console.lo ...

Utilize Webpack to import a file containing exclusively global constants

I have a specific file filled with essential global constants that I am attempting to bring into another JavaScript file. This way, I can utilize these constants within the code of the second file. globalConstant.js global.RoutesOffersPage = { routes: ...

I am seeking a way to conceal text in an HTML document using JavaScript when the browser window width is less than a specified amount, and reveal it when the window width exceeds that value

I attempted to use the window.screen.width method, but it appears that the script only runs once (upon page load). I am seeking a way for the code to run continuously. Below is my JavaScript snippet: var textinSelected = document.getElementById("se ...

Error message for empty input is not being displayed upon submission in Bootstrap validation

I've been attempting to implement Bootstrap validation in a form with the following desired outcome: Upon submission of the form, if the "First name" field is left empty, a message saying "Please enter a name" should appear below the field. If the f ...