Vue: update data and trigger function upon completion of animation transformation, utilizing animation transformation completion listener

Check out this straightforward Vue example: https://codesandbox.io/s/sleepy-haze-cstnc2?file=/src/App.vue

https://i.stack.imgur.com/zboCb.png

Whenever I click on the square, it not only changes color but also expands to 200% of its original size with a 3-second transition period for scaling.

https://i.stack.imgur.com/ignib.png

I'm looking to figure out how to turn the square green once the scaling animation is finished using Vue.

<template>
  <div id="container">
    <div
      id="box"
      v-on:click.stop="this.clickAction"
      :class="this.isClicked ? ' changed' : ''"
    ></div>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},

  data() {
    return {
      isClicked: false,
    };
  },

  methods: {
    clickAction() {
      console.log("click");
      this.isClicked = true;
    },
  },
};
</script>

<style>
#container {
  height: 100vh;
  width: 100vw;

  display: flex;
  justify-content: center;
  align-items: center;
}

#box {
  background-color: brown;
  padding: 2em;
  margin: 2em;

  width: 100px;
  height: 100px;
}

#box:hover {
  cursor: pointer;
  opacity: 80%;
}

.changed {
  background-color: cyan !important;

  transform-origin: center;
  transition: transform 3s;

  transform: scale(2);
}
</style>

Answer №1

You have the option to assign names of classes instead of using a boolean value in the isClicked property and incorporate the setTimeout function to delay for 3 seconds:

new Vue({
  el: "#demo",
  data() {
    return {
      isClicked: '',
    };
  },
  methods: {
    clickAction() {
      this.isClicked = 'changed';
      setTimeout(() => {
        this.isClicked = 'stopped';
      }, 3000)
    },
  },
})
#container {
  height: 100vh;
  width: 100vw;

  display: flex;
  justify-content: center;
  align-items: center;
}

#box {
  background-color: brown;
  padding: 2em;
  margin: 2em;

  width: 100px;
  height: 100px;
}

#box:hover {
  cursor: pointer;
  opacity: 80%;
}

.changed {
  background-color: cyan !important;

  transform-origin: center;
  transition: transform 3s;

  transform: scale(2);
}
.stopped {
  background-color: green !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div id="container">
    <div
      id="box"
      v-on:click.stop="clickAction"
      :class="isClicked"
    ></div>
  </div>
</div>

Alternatively, you can utilize ref and listen for the transitioned event:

new Vue({
  el: "#demo",
  data() {
    return {
      isClicked: '',
    };
  },
  methods: {
    clickAction() {
      this.isClicked = 'changed';
      const elem = this.$refs.box;
      elem.addEventListener('transitionend', event => {
        if (event.target === event.currentTarget) {
          this.isClicked = 'stopped';
        }
      });
    },
  },
})
#container {
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}
#box {
  background-color: brown;
  padding: 2em;
  margin: 2em;
  width: 100px;
  height: 100px;
}
#box:hover {
  cursor: pointer;
  opacity: 80%;
}
.changed {
  background-color: cyan !important;
  transform-origin: center;
  transition: transform 3s;
  transform: scale(2);
}
.stopped {
  background-color: green !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div id="container">
    <div
      ref="box"
      id="box"
      @click="clickAction"
      :class="isClicked"
    ></div>
  </div>
</div>

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

What specific width range would be best for my needs?

I used to have the default font style of Myriad Pro Light and a padding setting for my main menu on my website as follows: .menu > li > a { padding: 17px 15px 15px 15px; } Recently, I changed the default font style to Montserrat. However, this chang ...

Setting a constant width for text characters across all devices using CSS and HTML

I am looking to display text in my textarea with the same width in pixels across all devices. Essentially, I want to set the character width in pixels so that it appears consistently on any device (Desktop/Mobile). <html> <head> <styl ...

What are your thoughts on combining a JSON object with HTML?

When using ASP.NET MVC, it is possible to return a JSONResult. return JSON(new { View = RenderViewAsString("MyView", model), wasSuccessful = true}) This approach combines HTML and data in a single JSON object. The goal is to utilize strongly typed HtmlHe ...

Having trouble with npm install, unable to successfully install any node modules after cloning my project from git

I recently pulled my project from a git repository and encountered issues while attempting to run npm install. Despite trying different solutions like running npm install --save core-js@^3 to address the core-js error, I keep receiving the same message pr ...

Arrange database by website domain in PHP

I'm facing an issue where I need to extract domain names from a database and build buttons that can be used to sort the database based on these domains. For example, clicking on the Gmail button should sort users with Gmail accounts, and clicking on t ...

Click on an Object within a modal window using JavaScript in Internet Explorer 8

I'm facing a strange issue with the SELECT object in a Modal Window. Within my HTML code, I have a button that opens a modal window when clicked. Inside this modal window, a JSP page is loaded. On this JSP page, there is a dropdown list created using ...

Encountering issues with Vue-Router functionality after refreshing page in Laravel-6

Can someone explain what is going on here? Whenever I refresh my web browser, it no longer recognizes the route. ...

What is the best way to create a clickable button link using PHP echo?

Whenever I click the button, it always redirects to just story.php, ignoring all other details. I attempted using JavaScript but I found that utilizing form action is the closest method for me to accomplish this: <form action='./story.php?u=$id&a ...

Create a full-width slider using Materialize CSS framework

When using materializecss to create a slider, I encountered an issue where the image is full width but not full height, causing scrollbars to appear. What changes can I make to ensure the slider fills out my screen without any scrollbars? Additionally, I ...

Laravel Mix fails to recognize VueJs integration in Laravel

Having an issue setting up VueJs with laravel 5.7 and mix where it keeps saying VueJs is not detected. I've already executed the npm install command. Below is my welcome view: <!doctype html> <html lang="{{ str_replace('_', '- ...

Calculating the sum of all values in the database

In my database, I have a value called task_time. I want to add this value to itself so that the total time is calculated as totalTime = task_time + task_time + ... + task_time. This is how I retrieve the data: function getEndTasks() { $http.get(& ...

Creating a notification for specific choices in a dropdown menu

I am working on a form that includes a select element with multiple options. Depending on the option selected, a different form will be displayed. My concern is if a user starts filling out one form and then decides to select another option, I want to add ...

The Django server fails to display the CSS files upon activation

Despite having all the static files in place, only the plain HTML loads without any styles for some unknown reason. I've attempted using collectstatic and even setting up a new project, but to no avail. STATIC_URL is also properly specified along with ...

Display a list of items using ReactJS by mapping through an array of objects and rendering based on

How can I render a set of <div> </div> based on the items in an object without having to specify their names? In the code snippet below, I want the display of WorkObjectID and WorkObjectVal to be dynamic rather than static. If I include TempOb ...

angular2 angular-entity directive

I have developed a component that accepts a template: export class TemplateParamComponent implements OnInit { @Input() items: Array<any>; @Input() template: TemplateRef<any>; } Here is the HTML code: <template #defaultTemplate le ...

Traversing through objects in react.js

Hello there, I'm currently learning React and JavaScript but facing some challenges with a particular task. Let's dive into it! So, imagine I have an array like this: clients = ["Alex", "Jimmy"] and then I proceed to create another array using th ...

Elements with absolute positioning are preventing drag events from executing

Struggling to create a slider and encountering an issue. The problem lies in absolute items blocking slider drag events. I need a solution that allows dragging the underlying image through absolute positioned items. Any ideas on how to achieve this? MANY T ...

Creating a new function within the moment.js namespace in Typescript

I am attempting to enhance the functionality of the moment.js library by adding a new function that requires a moment() call within its body. Unfortunately, I am struggling to achieve this. Using the latest version of Typescript and moment.js, I have sear ...

Accordion feature that loads JSON data dynamically with AJAX

I am facing a challenge with my HTML structure and corresponding CSS styling. The HTML code includes an accordion container with multiple sections that can be expanded or collapsed. <div class="accordion-container"> <ul class="accordion"> ...

The sequence of indices in a for loop and making Ajax requests

I'm dealing with a challenge related to executing ajax requests within a for loop. Despite researching solutions online and implementing them to prevent synchronous request execution, I still face an issue in maintaining the correct order of the succe ...