javascript - 如何在不延迟的情况下正确获取 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 box-sizing 属性的值如何。从 jQuery 1.8 开始,这可能需要检索 CSS 宽度加上 box-sizing 属性,然后当元素具有 box-sizing:border-box 时减去每个元素上的任何潜在边框和填充。为避免这种惩罚,请使用 .css("width") 而不是 .width()。
推荐阅读
- python - 熊猫滚动计算 - 添加百分比变化
- java - 基于输入在java中动态创建对象类
- java - Spring Boot 自动配置和属性
- javascript - 如何从具有匿名函数的 div 中删除事件侦听器
- python-3.x - 如何在python中多拆分列
- spring - 我无法在 Jpa 单元测试中从 H2 获取我的数据
- node.js - `Extensions` 字段未显示在 apollo graphql 响应数据中
- python - 尽管训练是 100%,但无法提高验证准确度以及如何将从视频中提取的图像提供给深度学习模型
- datepicker - 在 datePicker 中禁用手动输入日期
- javascript - 我应该避免使用 px 使 react-app 移动友好吗?