javascript - 如何在不延迟的情况下正确获取 setInterval 内的某些元素宽度?

标签 javascript jquery css drop-down-menu

我正在尝试使用 setInterval 增加一些进度条。当我测试时,它工作正常。

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>

由于我将其嵌套在下拉菜单中,因此我在重复每个操作的时间上遇到了麻烦:

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/popper.js@1.16.0/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>

当我打开下拉菜单时,进度条宽度将会增加。但是当我尝试不同的值来重复该操作时,出现了问题。

在示例中,如果我将值设置为 100或更低,我会错误地获取进度条宽度。默认宽度值为 0 ,增加后(通过添加 1 ),为什么它是 0.15625然后0.3125 ...?

再尝试一次,如果我将值设置为 300或更高,我正确得到宽度 (0, 1, 2...)

有人知道为什么吗?

最佳答案

使用 css 宽度属性代替 jQuery width()方法自 width()可能会返回不可靠的数据。

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/popper.js@1.16.0/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>

取自 docs :

Note that .width() will always return the content width, regardless of the value of the CSS box-sizing property. As of jQuery 1.8, this may require retrieving the CSS width plus box-sizing property and then subtracting any potential border and padding on each element when the element has box-sizing: border-box. To avoid this penalty, use .css( "width" ) rather than .width().

关于javascript - 如何在不延迟的情况下正确获取 setInterval 内的某些元素宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59599128/

相关文章:

javascript - 如何使鼠标悬停时图像与鼠标交互?

javascript - 如何停止在同一对象上触发 'tap' 事件

javascript - 我可以使用哪个函数代替 parseJSON jquery 版本 1.3.2

javascript - 是否可以在没有服务器的情况下从客户端应用程序中的 API GITHUB 获取 token 和 client_id ?

javascript - 如何在 Web SQL 数据库中插入多行?

javascript - 悬停父元素上的类更改跨度

JavaScript 将文本粘贴到带有删除格式的 contenteditable

javascript - 如何将像素坐标转换为等距网格坐标?

javascript - 提交表单时如何发送JSON请求参数? (而不是 $.ajax 请求)

html - 复选框CSS样式看起来像已禁用