attach an event handler to dynamically generated elements after they are rendered

I am attempting to attach an event to dynamically rendered elements, and below is my approach.

<div id="app">
    <a href="#" @click="loadData">Load Data</a>
    <ul>
        <li class="collections" v-for="item in collections" :key="item.id">{{ item.name }}</li>
    </ul>
</div>

new Vue({
  el : '#app',
  data : {
    files : []
  },
  mounted(){
    const _self = this;
    axios.get('myapi.com/api/users',{})
    .then(function(res){
      _self.files = res.data.users;

      // add event
      document.querySelectorAll('.collections').forEach(function(el){
        _self.$ons.GestureDetector(el).on("hold", function(event) {
          alert();
        });
      });

    });
  },
  computed : {
    collections(){
      return this.files;
    }
  },
  methods : {
    loadData(){
      const _self = this;
      axios.get('myapi.con/api/users/2',{})
      .then(function(res){
        _self.files = res.data.users;
        document.querySelectorAll('.collections').forEach(function(el){
            _self.$ons.GestureDetector(el).on("hold", function(event) {
                alert();
            });
        });
      });
    }
  }

});

It appears that updating the DOM element is done asynchronously. When I tried

console.log(document.querySelectorAll('.collections').length)
, it returned 0. However, checking via console showed the correct number of target elements.

Note: manually binding the event serves a specific purpose, even though I could use the standard @click in Vue.

Answer №1

There are two main challenges to tackle here: 1) Setting up a customized hold event from an external library, and 2) Interacting with the DOM of a v-for item post-mounting. To address these issues effectively, it is recommended to create a separate component for each collections item and utilize the mounted hook within that component:

1. Develop a custom component specifically for the collections items, passing the item as a prop

Vue.component('collection-item', {
  props: ['item'],
  template: `<li>{{ item.name }}</li>`,
  mounted() {
    // WHERE YOU SHOULD ADD YOUR CUSTOM EVENT HANDLING LOGIC
    // Eliminate the need for `_self` by using arrow functions
    // this.$el refers to the respective DOM element
    this.$ons.GestureDetector(this.$el).on("hold", event => {
      alert(event);
    });
  }
})

2. Make necessary adjustments to your template structure

<ul>
  <collection-item v-for="item in collections" :key="item.id" :item="item" />
</ul>

3. Cleanse the main app component by removing all event handler codes

Key points to consider:

  • Within the custom component's mounted hook, you can efficiently target the DOM element using this.$el.
  • If you opt for an arrow function, there is no requirement for the _self workaround.

For further understanding, refer to this demo on JSFiddle. The demo may show errors due to unfamiliarity with the GestureDetector functionality, but it serves as a valuable learning resource.

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

Manipulate the text within a swf file using jQuery

Looking for a solution to target links inside a SWF file connected to XML without access to the .fla or .swf files. Is there a way to achieve this using jQuery or Javascript? Any help is appreciated. ...

Adjust the z-index of the Y-axis border in ApexCharts to position it behind the marker

https://i.sstatic.net/LS68G.png Struggling to ensure the y-axis border stays behind the marker, any assistance would be appreciated. Explore it on CodeSandbox : https://codesandbox.io/s/apexcharts-forked-znw38y?file=/src/index.js ...

The Chrome extension takes control of the new tab feature by redirecting it to a custom newtab.html

I have a website https://example.com where users can adjust their site preferences, including enabling night mode. To enhance the user experience, I developed a Chrome extension for https://example.com that transforms Chrome's new tab with a custom ne ...

Unable to retrieve nested object from an immutable object

How can I access an Array in an object? I want to display the entire list. render() { var elems = this.props.items.course_list; console.log(elems); return ( <div> </div> ) } Here is a visual representation: htt ...

Transform an array into JSON format in Javascript using the same key

Within my PHP file, I have a list of file names from a specific folder that I need to convert into JSON format. The array containing the file names looks like this: Array ( [0] => teste3.pdf [1] => teste2.pdf [2] => teste.pdf ...

Display the table once the radio button has been selected

Before we proceed, please take a look at the following two images: image 1 image 2 I have over 20 fields similar to 'Image 1'. If "Yes" is selected, then a table like in 'Image 2' should be displayed. This means I have 20 Yes/No fields ...

What is the process for programmatically injecting a search query to activate the places_changed event for the Google Maps API?

Currently, I am working on a search page that includes a location input field. My goal is to automatically populate this input with a query if a user reaches the page from another source with a search query. Additionally, I want to trigger a place change e ...

Google Chrome Android app cannot effectively validate Regx, while it functions seamlessly on Chrome Browser for PCs

I have implemented a Regex validation to allow only alphabetic characters (text only values) in a text field. The validation works perfectly on a PC, but when accessed through an Android device using the Chrome app, it seems like the validation is not effe ...

Resolved issue with sticky header movement after scrolling event

I've been working on a sticky header code, but I'm having trouble achieving a smooth scroll transition. The fixed header seems to jump after just one scroll. Here is the basic HTML structure: <div class="headerWrapper"> <div id="to ...

What is the appropriate time to end a connection in MongoDB?

Utilizing Node.js Express and MongoDB for my API, I encountered an issue with the mongoClient connection. The data fetching process worked smoothly at first, but without refreshing it threw an error stating "Topology is closed." const express=require("e ...

Tips for expanding button width in 'react-native-swipeout' to enable swipe action on ListView row (React Native)

Currently, I am exploring how to implement the component found here: https://github.com/dancormier/react-native-swipeout My goal is to have the row swiped all the way. Is there a method to increase the button width so that it covers the entire width of th ...

Retrieve data with Vue Js when a user clicks and dynamically add it to a modal window

I am faced with a situation where I have a parent component and a child component which acts as a modal popup. Parent Component: <parent-component> <!-- Child component acting as a modal popup --> <child-component v-bind ...

When images in Ionic overlap with the side menu bar

Currently, I am in the process of developing an Android app using the IONIC framework. Within this project, I have created three divisions that contain images with shadows applied to them. However, I am encountering an issue where the side menu bar is over ...

What is the best way to show a message box in ASP.NET?

I've been trying to display a message box after successfully saving an item, but the solutions I found online haven't worked for me. Below is the code I'm currently using: try { con.Open(); string pass="abc"; cmd = new SqlComman ...

What is the best way to retrieve the row IDs in react-table?

Using table-v7 and attempting to implement a delete modal, but unsure of how to retrieve the ids of my rows and set them in my axios request The function is located in a hook file, and if I use row.original._id, I can obtain the id but it only works withi ...

Exploring the Distinctions among JavaScript Objects

Currently facing a challenging problem and in search of an efficient solution. I have two Javascript Objects structured as {id:data, id:data, ..} If we focus solely on the Keys, they appear like this: B = ["1","2","3"] A = ["2","3","4"] My goal is ...

Is there a way to display a single div id from an external html file within a popup modal?

I have a dilemma with my external HTML content that is being displayed in a popup modal using an awesome library called jQuery Modal. Currently, the entire page displays perfectly within the modal, but I am aiming to only reveal one specific div each time ...

What is preventing AJAX from displaying the updated JSON content?

I'm brand new to JavaScript and I'm trying to send an ajax request to retrieve the contents of a JSON file and display it in a div. Here's the code I currently have: <!DOCTYPE html> <html> <head> <script src="https: ...

I aim to assign a unique identifier to each todo item that is displayed

function handleChange(event) { event.preventDefault() updateItem(event.target.value) } Within this function, my goal is to assign a unique id to each todo element. function addNewTodo(event) { event.preventDefault() setItem({ id: 0 }) ...

Vue looping through an object containing arrays

I am facing an issue with my code where I need to iterate over multiple objects with arrays, but no return data is being displayed. Can someone please help me with my code? Here is a sample of JSON data retrieved from an API: "sections": [ ...