What is the best way to ensure that my transitionend event is triggered?

I'm currently exploring the <progress> element and attempting to incorporate a CSS transition to achieve a smooth progress bar effect as its value increases. Despite my efforts, I can't seem to trigger JS after the transitionend event occurs.

Where could I be making a mistake?

$("button").on("click", function () {
    $("progress").val(100);
});

$("progress[value]").on(
    "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",
    function () {
        $("progress").val(0);
        alert("Completed");
    }
);
body {
    margin: 0;
    padding: 0;
    text-align: center;
}

button {
    margin: 10px;
    text-transform: uppercase;
    font-size: 1em;
}

.loadPageProgress progress {
    display: block;
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: green;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
}

.loadPageProgress progress[value] {
    background-color: green;
    transition: all 1000ms ease-in-out;
    -webkit-transition: all 1000ms ease-in-out;
    -moz-transition: all 1000ms ease-in-out;
    -o-transition: all 1000ms ease-in-out;
}

.loadPageProgress progress[value]::-webkit-progress-bar {
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: grey;
}

.loadPageProgress progress[value]::-webkit-progress-value {
    background-color: green;
    transition: all 1000ms ease-in-out;
    -webkit-transition: all 1000ms ease-in-out;
    -moz-transition: all 1000ms ease-in-out;
    -o-transition: all 1000ms ease-in-out;
}

.loadPageProgress progress[value]::-moz-progress-bar {
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="loadPageProgress">
    <progress value="0" max="100"></progress>
</div>

<button>start transition</button>

Answer №1

.val(x) function does not trigger a transition on the progress element; it updates instantly. The transition you see is actually on the pseudo element ::-webkit-progress-value, which cannot be targeted with jQuery as it is not part of the DOM.

You can observe this by removing the transitions from the CSS of your pseudo-element. Without the transition, the progress updates instantly.

Instead of using .val(), consider utilizing .animate or a similar method to update your progress bar and receive completion callbacks or step functions. Refer to code snippet #2 for an example implementation of this.

Snippet 1: Pseudo Transitions Removed.

$("button").on("click", function () {
    $("progress").val(100);
});

$("progress[value]").on(
    "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd",
    function () {
        $("progress").val(0);
        alert("Completed");
    }
);
body {
    margin: 0;
    padding: 0;
    text-align: center;
}

button {
    margin: 10px;
    text-transform: uppercase;
    font-size: 1em;
}

.loadPageProgress progress {
    display: block;
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: green;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
}

.loadPageProgress progress[value] {
    background-color: green;
    transition: all 1000ms ease-in-out;
    -webkit-transition: all 1000ms ease-in-out;
    -moz-transition: all 1000ms ease-in-out;
    -o-transition: all 1000ms ease-in-out;
}

.loadPageProgress progress[value]::-webkit-progress-bar {
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: grey;
}

.loadPageProgress progress[value]::-webkit-progress-value {
    background-color: green;
}

.loadPageProgress progress[value]::-moz-progress-bar {
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="loadPageProgress">
    <progress value="0" max="100"></progress>
</div>

<button>start transition</button>

Snippet 2: Animate

$("button").on("click", function () {
    $("progress").animate({value:100},{
      duration:2000,
      step: function(x){
        
      },
      complete: function(){
        console.log("Done!");
      }
    });
});
body {
    margin: 0;
    padding: 0;
    text-align: center;
}

button {
    margin: 10px;
    text-transform: uppercase;
    font-size: 1em;
}

.loadPageProgress progress {
    display: block;
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: green;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
}

.loadPageProgress progress[value] {
    background-color: green;
    transition: all 1000ms ease-in-out;
    -webkit-transition: all 1000ms ease-in-out;
    -moz-transition: all 1000ms ease-in-out;
    -o-transition: all 1000ms ease-in-out;
}

.loadPageProgress progress[value]::-webkit-progress-bar {
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: grey;
}

.loadPageProgress progress[value]::-webkit-progress-value {
    background-color: green;
}

.loadPageProgress progress[value]::-moz-progress-bar {
    width: 100%;
    height: 5px;
    border: none;
    border-radius: 0;
    background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="loadPageProgress">
    <progress value="0" max="100"></progress>
</div>

<button>start transition</button>

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

Use jQuery AJAX to add a new record to a webmethod and refresh the dropdown list with the updated

After successfully adding a record via a jQuery AJAX call to a web method, I would like to update the dropdown list without using an update panel. What is the most efficient way to accomplish this? Thanks! ...

What could be causing my Bootstrap carousel to only slide once?

I'm currently working on integrating a Bootstrap Carousel into my website, but I've encountered an issue where it moves only once and then becomes unresponsive. After checking the file order, I couldn't find any issues there. So, I'm qu ...

Implementing shallow routing with the Next.js 13 framework while having appDir functionality activated

Previously in Next 13 (or with appDir disabled), you could achieve the following: const MyComponent = () => { const router = useRouter(); const toggleStatic = () => { if (router.query.static) { router.push(router.pathname, router.pa ...

Is it necessary to specify the server-side script within the "routes" directory?

I'm currently developing a NodeJS Express application and from what I gather, the communication between the server and client is achieved by incorporating an AJAX script in a JavaScript file (on the client-side) and implementing a listener function (f ...

Sort your list efficiently with a custom hook in React using Typescript

I've been working on developing a custom hook in React that sorts an array based on two arguments: the list itself and a string representing the key to sort by. Despite trying various approaches, I haven't been able to find a solution yet. I&apos ...

HTML5 - Adding Space to Main Section with a Two-column Layout

After spending 3 and a half hours racking my brain, I still can't figure out how to complete two seemingly simple tasks. First, I need to pad the outside of paragraph div, and secondly, I want to split the main section into two columns to add some lin ...

Submitting a form after receiving a response from an AJAX request in ASP.NET

My website features a login and registration popup on an aspx page. The popup contains two submit buttons, one for logging in and the other for registering. When the user clicks on the registration button, I check the email availability using jQuery ajax. ...

A guide on validating dates in Angular Ionic5 with the help of TypeScript

I have tried multiple solutions, but none seem to work when validating the current date with the date entered by the user. The date is passed from the user into the function parameters, but how do I perform validation? How can I validate the date? isToday( ...

BottomNavigation wrapping React Router is failing to load the updated component

I'm struggling to understand why I can't seem to load the DMO page from a BottomNavigation component. Navigating to "/dom" works fine, but clicking the buttons doesn't do anything. The initial "/" loads perfectly. Any ide ...

The CKEditor value is set to the result of the dropdown selection

I need to implement a dropdown feature on my form where the options correspond to titles of content in my database. Once an option is selected, I want the corresponding content to display in a CKEditor field. I'm attempting to achieve something simil ...

Guide to dynamically altering the header logo as you scroll further

I'm attempting to dynamically change the logo in my header based on how far I've scrolled down the page. While I have experimented with libraries like Midnight.js, I specifically need to display an entirely different logo when scrolling, not just ...

Serve unique data to different bots and human visitors using express.js and node.js

I am looking for a method to differentiate between bot (such as google or bing) and human incoming requests, in order to provide tailored data to each. This could include serving json data for client-side javascript to build the site or preprocessed html. ...

How to access additional legend labels in c3.js or billboard.js using JSON data?

I'm working with the following code snippet: ... normen is my json object .... $.each(normen, function(item) { chartX.push(this.feed_day) chartY.push(this.weight) }); createChart(char ...

Is it conceivable to exploit JSON responses with appropriate JavaScript string escaping to launch an XSS attack?

Exploiting JSON responses can occur when Array constructors are overridden or when hostile values are not properly JavaScript string-escaped. To combat this, Google has implemented a technique where all JSON responses are prefixed with a specific code sni ...

automatically changing radio button selection based on dropdown choice

Let's address the issue at hand: I have a dropdown list with over three options, and alongside it, a radio group for yes or no responses. What I am aiming to achieve is setting the radio button to "no" when option 1 is selected, and to "yes" when any ...

In my Vue watch method, I have two parameters specified, and one of them remains constant without any changes

Currently, I am attempting to access a method within my watch function with two parameters. Here is the code snippet for the method: onBoolianChange(value, willChange) { willChange = (value === false) ? true : false; }, watch: { "e ...

Showing a DIV multiple times with an additional text field in HTML and JS

As someone new to development, I am facing a requirement where I need to create a form with a dynamic field that can be added or removed using buttons. When the user clicks on the Add button, another field should appear, and when they click on Remove, the ...

When the section comes into view on the screen, the CSS animation will play only one time

While browsing through , I found some fantastic animations that inspired me. The animations at the header seem to be standard CSS animations with delays. However, as you scroll down and other sections become visible, the animations reappear only once. Can ...

What is the most efficient way to prevent duplicate items from being added to an array in a Vue 3 shopping cart

I currently have a functional shopping cart system, but I am facing an issue where it creates duplicates in the cart instead of incrementing the quantity. How can I modify it to only increment the item if it already exists in the cart? Also, I would like t ...

From JSON to HTML: the beauty of nesting

I believe there might be a foolish error lurking in my code, waiting to be uncovered. I am working with JSON data sourced from an external site at . The goal here is to extract specific data elements, such as stationShortCode, type, commercialTrack, and s ...