我的JavaScript按钮事件监听器有一个错误。

huangapple go评论71阅读模式
英文:

My javascript event listener for a button is having a bug

问题

我正在尝试制作一个非常基本的RPG游戏,在这个游戏中,当你攻击时,经验条的宽度会减少20px的CSS宽度。现在我已经做到了,一切似乎都运行良好,但后来我注意到一个bug,当我点击攻击按钮更快时。经验值在某个点上不会减少20px。它可能只会减少10px,甚至可能是3px。我不确定是我的数学实现有问题,还是我尚未找出的bug。

以下是我的JavaScript代码:

const atkBtn = document.getElementById("atk-btn");
let expBar = document.getElementById("bar");

function attack(){
    var barWidth = expBar.offsetWidth;
    var atkVal = 20;
    newBar = (barWidth - atkVal)+"px";
    expBar.style.maxWidth = newBar;
    console.log(newBar)
}

atkBtn.addEventListener("click", attack);

以下是我的CSS代码:

p{
    margin: 0px;
    display: inline-block;
}

#bar{
    width: 200px;
    height: 15px;
    margin-top: 10px;
    background-color: red;
    display: inline-block;
    max-width: 200px;
    overflow-x: hidden;
    transition: all 0.4s;
}

以下是当我慢慢点击按钮时的情况:
我的JavaScript按钮事件监听器有一个错误。

以下是当我快速点击按钮(模拟游戏条件)时的情况:
我的JavaScript按钮事件监听器有一个错误。

如果您有任何答案,请随时回复。谢谢。

英文:

I am trying to make a very basic RPG game where when you attack, the exp bar will decrease by 20px in css width.
Now that I have done it and everything seems to be working well, but then I noticed a bug when I clicked the attack button faster. The exp value is not decreasing by 20px at some point. It might just decrease by 10px or maybe even 3px. I am not sure if my math implementation is wrong or it's a bug that I am yet to figure out.

Here is my javascript code :

const atkBtn = document.getElementById("atk-btn");
let expBar = document.getElementById("bar");

function attack(){
    var barWidth = expBar.offsetWidth;
    var atkVal = 20;
    newBar = (barWidth - atkVal)+"px";
    expBar.style.maxWidth = newBar;
    console.log(newBar)
}

atkBtn.addEventListener("click", attack);

Here is my css code :

p{
    margin: 0px;
    display: inline-block;
}

#bar{
    width: 200px;
    height: 15px;
    margin-top: 10px;
    background-color: red;
    display: inline-block;
    max-width: 200px;
    overflow-x: hidden;
    transition: all 0.4s;
}

Here is when I clicked the btn slowly:
我的JavaScript按钮事件监听器有一个错误。

Here is when I clicked the btn faster(to simulate gaming condition):
我的JavaScript按钮事件监听器有一个错误。

Should you have any answer please feel free to reply. Thanks

答案1

得分: 2

这是代码部分,不需要翻译。

如果两次点击的时间间隔小于 0.4s,样式仍然会随着时间的推移而改变,并且后一次点击的计算将基于您在点击时的过渡状态。完全移除过渡效果可以解决这个问题。

要将过渡效果保留为动画,可以单独跟踪正在进行的宽度。基本上,不要使用样式来存储数据。而是将数据单独存储,并从中构建样式。例如:

const atkBtn = document.getElementById("atk-btn");
let expBar = document.getElementById("bar");
let barWidth = 200;

function attack(){
    var atkVal = 20;
    barWidth -= atkVal;
    newBar = barWidth + "px";
    expBar.style.maxWidth = newBar;
    console.log(newBar)
}

atkBtn.addEventListener("click", attack);
p{
    margin: 0px;
    display: inline-block;
}

#bar{
    width: 200px;
    height: 15px;
    margin-top: 10px;
    background-color: red;
    display: inline-block;
    max-width: 200px;
    overflow-x: hidden;
    transition: all 0.4s;
}
<button id="atk-btn">Attack</button>
<div id="bar"></div>
英文:

This:

transition: all 0.4s;

If two clicks are faster than 0.4s apart, the style is still changing over time and the calculation for the latter click will be based on wherever you are in the transition when clicking. Removing the transition entirely fixes the issue.

To keep the transition as an animation, track the ongoing width separately. Basically, don't use the styling to store data. Instead, store the data separately and build the styling from it. For example:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const atkBtn = document.getElementById(&quot;atk-btn&quot;);
let expBar = document.getElementById(&quot;bar&quot;);
let barWidth = 200;

function attack(){
    var atkVal = 20;
    barWidth -= atkVal;
    newBar = barWidth+&quot;px&quot;;
    expBar.style.maxWidth = newBar;
    console.log(newBar)
}

atkBtn.addEventListener(&quot;click&quot;, attack);

<!-- language: lang-css -->

p{
    margin: 0px;
    display: inline-block;
}

#bar{
    width: 200px;
    height: 15px;
    margin-top: 10px;
    background-color: red;
    display: inline-block;
    max-width: 200px;
    overflow-x: hidden;
    transition: all 0.4s;
}

<!-- language: lang-html -->

&lt;button id=&quot;atk-btn&quot;&gt;Attack&lt;/button&gt;
&lt;div id=&quot;bar&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

答案2

得分: 1

以下是翻译好的内容:

在这个条形图上有一个过渡效果:
```css
#bar{
    ...
    过渡: 全部 0.4秒;
}

而且,由于您正在使用条形图的当前宽度,在过渡结束之前点击时,您会得到一个高于预期值的值,因为条形图尚未完全减少。

总的来说,我建议将数据与布局分离,即将HP存储在一个变量中,并从中派生条形图的长度,而不是直接使用条形图的长度。类似这样:

var hp = 200

function updateBarWidth(){
  expBar.style.maxWidth = hp + 'px';
}

updateBarWidth()

function attack(){
    var atkVal = 20;
    hp - atkVal
    updateBarWidth()
}

<details>
<summary>英文:</summary>

There is a transition effect on the bar:

#bar{
...
transition: all 0.4s;
}

and since you are using the current width of the bar, if you click before the transition has ended, you get a value above the expected one, since the bar has not yet decreased fully.

In general, I would suggest separating the data from the layout, i.e. store the HP in a variable and derive bar length from it, instead of using the bar length directly. Something like:

var hp = 200

function updateBarWidth(){
expBar.style.maxWidth = hp + 'px';
}

updateBarWidth()

function attack(){
var atkVal = 20;
hp - atkVal
updateBarWidth()
}


</details>



# 答案3
**得分**: 0

你设置的是 `maxWidth` 而不是 `width`,所以攻击函数应该如下所示:

```javascript
function attack(){
  var barWidth = expBar.offsetWidth;
  var atkVal = 20;
  newBar = (barWidth - atkVal) + "px";
  expBar.style.width = newBar;
  console.log(newBar)
}
英文:

You are setting the maxWidth instead of width, so the attack function should look like this:

function attack(){
  var barWidth = expBar.offsetWidth;
  var atkVal = 20;
  newBar = (barWidth - atkVal)+&quot;px&quot;;
  expBar.style.width = newBar;
  console.log(newBar)
}

huangapple
  • 本文由 发表于 2023年7月20日 20:46:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76730056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定