JavaScript 进度条不适用于 OO JS 代码 [英] JavaScript progress bar does not work with OO JS code
问题描述
我正在尝试以面向对象的方式重新编写此演示:https://www.w3schools.com/howto/howto_js_progressbar.asp这是我的代码:
document.getElementById("barButton").addEventListener("click", callMove);函数调用移动(){var bar1 = new ProgressBar();bar1.move();}功能进度条(){this.elem = document.getElementById("myBar"),this.width = 1;}ProgressBar.prototype = {构造函数:ProgressBar,移动:函数(){this.id = setInterval(this.frame, 300);},框架:函数(){if(this.width >= 100) {clearInterval(this.id);}别的 {this.width++;if(this.width >= 50) {返回;}this.elem.style.width = this.width + '%';}},}
#myProgress {宽度:100%;背景颜色:灰色;}#myBar {宽度:1%;高度:30px;背景颜色:黑色;}
<头><标题>这是一个OO进度条测试.<link rel="stylesheet" href="testOOProgressBar.css">头部><身体><div id="myProgress"><div id="myBar"></div>
<br><button id="barButton">点击我</button><script src="testOOProgressBar.js"></script></html>
问题是,一旦我单击按钮,该栏就不会按我预期的那样进行,而是在控制台中出现 Uncaught TypeError: Cannot read property 'style' of undefined at frame
.这里有什么问题?this.width
似乎没有从 Progressbar()
传递给它的原型.
您的错误意味着您试图阅读以下内容:
undefined.style
通过检查代码,您可以看到错误来自Progressbar.frame
函数,并且只有一行包含.style
.
然后,看看它前面是什么:this.elem
...这是undefined
!
主要问题在于:
setInterval
在运行提供的函数时将 this
设置为全局对象.
您可以通过.bind()
:
document.getElementById("barButton").addEventListener("click", callMove);函数调用移动(){var bar1 = new ProgressBar();bar1.move();}功能进度条(){this.elem = document.getElementById("myBar"),this.width = 1;}ProgressBar.prototype = {构造函数:ProgressBar,移动:函数(){this.id = setInterval(this.frame.bind(this), 300);},框架:函数(){如果 (this.width >= 100) {clearInterval(this.id);} 别的 {this.width++;如果 (this.width >= 50) {返回;}this.elem.style.width = this.width + '%';}},}
#myProgress {宽度:100%;背景颜色:灰色;}#myBar {宽度:1%;高度:30px;背景颜色:黑色;}
<头><标题>这是一个OO进度条测试.<link rel="stylesheet" href="testOOProgressBar.css">头部><身体><div id="myProgress"><div id="myBar"></div>
<br><button id="barButton">点击我</button><script src="testOOProgressBar.js"></script></html>
I'm trying to re-write this demo in a OO way: https://www.w3schools.com/howto/howto_js_progressbar.asp This is my code:
document.getElementById("barButton").addEventListener("click", callMove);
function callMove(){
var bar1 = new ProgressBar();
bar1.move();
}
function ProgressBar() {
this.elem = document.getElementById("myBar"),
this.width = 1;
}
ProgressBar.prototype = {
constructor: ProgressBar,
move: function() {
this.id = setInterval(this.frame, 300);
},
frame: function() {
if(this.width >= 100) {
clearInterval(this.id);
}
else {
this.width++;
if(this.width >= 50) {
return;
}
this.elem.style.width = this.width + '%';
}
},
}
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: black;
}
<html>
<head>
<title>
This is a OO progress bar test.
</title>
<link rel="stylesheet" href="testOOProgressBar.css">
</head>
<body>
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button id="barButton">Click Me</button>
<script src="testOOProgressBar.js"></script>
</body>
</html>
Problem is, once I click the button, the bar does not progress as I expect, instead there is Uncaught TypeError: Cannot read property 'style' of undefined at frame
in console. What's wrong here? It seems that this.width
is not passed from Progressbar()
to its prototype.
Your error means that you tried to read something like this:
undefined.style
By inspecting the code, you can see that the error comes from the Progressbar.frame
function and it has only one line containing .style
.
Then, see what's before it: this.elem
... This is undefined
!
The main problem is that:
setInterval
sets this
to the global object when running the provided function.
You can avoid that by .bind()
:
document.getElementById("barButton").addEventListener("click", callMove);
function callMove() {
var bar1 = new ProgressBar();
bar1.move();
}
function ProgressBar() {
this.elem = document.getElementById("myBar"),
this.width = 1;
}
ProgressBar.prototype = {
constructor: ProgressBar,
move: function() {
this.id = setInterval(this.frame.bind(this), 300);
},
frame: function() {
if (this.width >= 100) {
clearInterval(this.id);
} else {
this.width++;
if (this.width >= 50) {
return;
}
this.elem.style.width = this.width + '%';
}
},
}
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: black;
}
<html>
<head>
<title>
This is a OO progress bar test.
</title>
<link rel="stylesheet" href="testOOProgressBar.css">
</head>
<body>
<div id="myProgress">
<div id="myBar"></div>
</div>
<br>
<button id="barButton">Click Me</button>
<script src="testOOProgressBar.js"></script>
</body>
</html>
这篇关于JavaScript 进度条不适用于 OO JS 代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!