如何在不延迟的情况下正确获取 setInterval 中的一些元素宽度?



我正在尝试使用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 width 属性代替 od jQuerywidth()方法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>

摘自文档:

请注意,.width(( 将始终返回内容宽度,而不管 CSS 框大小属性的值如何。从jQuery 1.8开始,这可能需要检索CSS宽度加box-ssize属性,然后在元素具有box-ssize:border-box时减去每个元素上的任何潜在边框和填充。要避免这种惩罚,请使用 .css( "width" ( 而不是 .width((。

最新更新