Is there a way to accurately retrieve the width of an element within setInterval without any delay?

I'm currently experimenting with increasing a progress bar using the setInterval function. So far, it seems to be functioning properly.

var progressBar = $('.progress-bar');

var count = 0;

var interval = setInterval(function () {
    var width = progressBar.width();

    console.log(width++);

    progressBar.width(width);

    count++;

    if (count === 101) {
      clearInterval(interval);
    }
}, 50);
.progress-bar {
  width: 0px;
  height: 4px;
  background-color: #00f;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<div class="progress-bar"></div>

However, when I tried nesting it into a dropdown, I encountered issues with the timing of repeating actions:

var increase = function (progressBar, ms) {
    var count = 0;

    var interval = setInterval(function () {
        var width = progressBar.width();

        console.log(width++);

        progressBar.width(width);

        count++;

        if (count === 21) {
          clearInterval(interval);
        }
    }, ms);
}

$('.dropdown').on('shown.bs.dropdown', function () {
    var progressBar = $(this).find('.progress-bar');
    
    increase(progressBar, +progressBar.data('ms'));
});
.progress-bar {
  width: 0px;
  height: 4px;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92e2fde2e2f7e0bcf8e1d2a3bca3a4bca2">[email protected]</a>/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

<div class="dropdown d-inline-block">
  <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Progress bar with 100ms
  </button>
  <div class="dropdown-menu" >
    <a class="dropdown-item" href="#">
        <div class="progress-bar" data-ms="100"></div>    
    </a>
  </div>
</div>

<div class="dropdown d-inline-block">
  <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Progress bar with 300ms
  </button>
  <div class="dropdown-menu">
    <a class="dropdown-item" href="#">
        <div class="progress-bar" data-ms="300"></div>    
    </a>
  </div>
</div>

Upon expanding the dropdown, the width of the progress bar increases. However, I've noticed that different values for repetition intervals yield unexpected results.

In this scenario, setting the value to 100 or lower leads to inaccurate width increments. The initial width value is 0, but after increasing by 1, why does it become 0.15625 and then 0.3125...?

On the other hand, when the value is set to 300 or higher, the width increments correctly (0, 1, 2...)

Any insights on why this is happening?

Answer №1

It's recommended to utilize the CSS width property instead of jQuery's width() method as width() may provide inaccurate data.

var increase = function (progressBar, ms) {
    var count = 0;
    var interval = setInterval(function () {
        var width = parseInt(progressBar[0].style.width) || 0;
        console.log(width++);
        progressBar[0].style.width = `${width}px`;
        count++;
        if (count === 21) {
          clearInterval(interval);
        }
    }, ms);
}

$('.dropdown').on('shown.bs.dropdown', function () {
    var progressBar = $(this).find('.progress-bar');
    
    increase(progressBar, +progressBar.data('ms'));
});
.progress-bar {
  width: 0px;
  height: 4px;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="19697669697c6b37736a592837282f3729">[email protected]</a>/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

<div class="dropdown d-inline-block">
  <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Progress bar with 100ms
  </button>
  <div class="dropdown-menu">
    <a class="dropdown-item" href="#">
      <div class="progress-bar" data-ms="100"></div>
    </a>
  </div>
</div>

<div class="dropdown d-inline-block">
  <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Progress bar with 300ms
  </button>
  <div class="dropdown-menu">
    <a class="dropdown-item" href="#">
      <div class="progress-bar" data-ms="300"></div>
    </a>
  </div>
</div>

Referencing information from the documentation:

Keep in mind that .width() will always return the content width, regardless of the value of the CSS box-sizing property. As of jQuery 1.8, this might involve fetching the CSS width along with the box-sizing property and then deducting any potential border and padding on each element when the element has box-sizing: border-box. To avoid this issue, opt for .css( "width" ) rather than .width().

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

JavaScript ES6 array method for generating an object from an array

I wish to transform the following array: [ { event: "LIB", block_calendar: "YES", obs: "Lorem Ipsum", status: "Block", }, { event: "LIB" block_calendar: "YES" o ...

Replicate the function of the back button following the submission of an ajax-submitted form to Preview Form

I am currently working on a multi-part form with the following data flow: Complete the form, then SUBMIT (using ajax post) jQuery Form and CodeIgniter validation messages displayed if necessary Preview the submitted answers from the form Options: Canc ...

Unable to save cookies on mobile browsers, but functioning properly on desktop computers

Currently, I am facing an issue with my ExpressJS app hosted on Heroku and a frontend React app hosted on Netlify. The problem arises when a user logs in successfully and is directed to the home page showing personalized content. Upon landing on the home p ...

displaying data once "other" is chosen from a dynamic chart

I am having an issue with a dynamic table where I have a dropdown list with the option "other", and I want to display additional input when "other" is selected. Currently, the function I have only hides the input that is always visible and does not show ...

Selenium C# dropdown reverts to initial state abruptly

I've been working on a project to validate some login accounts recently. I encountered an issue where, when I select the provider Canal Digitaal and click 'Login', the dropdown box reverts back to its original state. Manually, everything wor ...

What is the best way to modify the nested state of a dynamically generated state with the useState hook?

I'm currently facing a challenge when trying to update a nested property of a useState object. Here's the specific scenario: In the component, there is a prop "order" that contains multiple items (line_items) which represent the products in th ...

Invalidating the memory in iOS 7.1.1 when using canvas drawImage

When I use the following code on an animation frame, I notice a significant memory leak that eventually causes IOS Safari or Chrome to crash: ctx.drawImage(anotherCanvas, clipX, clipY, clipW, clipH, x, y, w, h); Interestingly, if I don't apply a ...

Utilizing Jquery's .GET method to retrieve and handle JSON data

In the jQuery snippet below, I am trying to fetch product data from . However, I am facing difficulty in iterating through the loop to access all 30 products along with their details. $.get("https://dummyjson.com/products/1") .done(function ...

Creating a square shape in Twitter Bootstrap to frame an item on a webpage

I've been working on creating a webpage that looks similar to the image provided. I've managed to get about 90% of it done, but there are a couple of issues I'm facing: How can I create a square with a triangle at the bottom as shown in th ...

Consistently obtaining the same outcome in JavaScript, always

Is it possible to resolve this issue? I keep getting a result of less than 18 when trying numbers 1-100, even though the output should be for values under 18. In my HTML code, there is a <p> element with id="result", an input with id=&quo ...

What is the best way to assign default values when destructuring interfaces within interfaces in TypeScript?

My goal here is to create a function that can be used with or without arguments. If arguments are provided, it should work with those values; if not, default values should be used. The issue I'm facing is that although there are no TypeScript errors ...

Retrieving Data using Map in ReactJS

I'm in the process of creating a web app and I have an array of data with URLs in each element. I'm struggling to figure out how to fetch data from these mapped URLs. useEffect(() => { axios .get(`someurl`) .then((response) =& ...

Achieving the display of font-weight 100 for Google web fonts successful

I have been experiencing difficulties in achieving the ultra-thin display of the Lato font through Google web fonts. Despite appearing correctly on Google's website, the font weight does not change when implemented on my own page if it is below 400 (I ...

Invoking a function in a React component from another component

I am trying to implement a page with the structure shown below: const Upload = (props) => { return ( <BaseLayout> <ToolbarSelection /> <Box> <FileDropArea /> </ ...

Incorporate the block-input feature from sanity.io into your next.js blog for enhanced functionality

Currently, I'm in the process of creating a blog using next.js with sanity.io platform. However, I am facing some difficulties when it comes to utilizing the code-input plugin. What's working: I have successfully implemented the code component b ...

Is there a way to send all the results of a Flask database query to a template in a way that jQuery can also access

I am currently exploring how to retrieve all data passed to a template from a jQuery function by accessing Flask's DB query. I have a database table with customer names and phone numbers, which I pass to the template using Flask's view method "db ...

Encountering a problem when looping through a JSON response

After making an Ajax call, I received the JSON response below. studentList: { "currentStudent":0, "totalStudent":11, "studentDetails": [{ "adId":1, "adName":"BMB X5", "sfImage":{ "imageName":"Desert", "image ...

vertically centering a div specifically on laptops

What is the best way to vertically center a div on lap-tops? (...) body {padding: 4% 16%;} body {top:0px; left:0px; bottom:0px; right:0px;} body {border: 12px solid darkred; border-style: double;} body {background-color: #FAFCB4;} p {font-size: 80%; text- ...

What are the steps to create a horizontal submenu in WordPress?

Is there a way to change the default vertical sub menu of my main menu to horizontal? The CSS for the sub menu in stylesheet.css is as follows: .main-nav>ul>li .sub-menu> li { padding:0 20px; } .main-nav>ul>li .sub-menu> li:first-ch ...

The preflight request's response failed to meet the access control criteria due to the absence of the 'Access-Control-Allow-Origin' header

I encountered an issue while using ngResource to call a REST API hosted on Amazon Web Services: Upon making the request to , I received the following error message: "XMLHttpRequest cannot load. Response to preflight request doesn't pass access cont ...