这是我第一次使用javascript。 我基本上想创建一个“点击器”游戏。 游戏的目标是单击图像以取得积分。 我已经尝试过自己修复它并在互联网上查找,但没有发现任何问题。 解决问题的原因是什么?
基本上,每次我打开页面时,分数已经设置为1,但是当我单击图像时分数不会增加。
<div id="bgk">
<div class="layer">
<div class="row p-2">
<div class="col-lg-6 col-xl-6 text-left"><p>Score: <span class="score"><script>document.write(scorecounter());</script></span></p></div>
<div class="col-lg-6 col-xl-6 text-right"><p>Time: <span class="time">2</span></p></div>
<div class="p-2">
<img src="png.png" id="image" onclick="scorecounter()">
</div>
</div>
</div>
</div>
这是增加分数的脚本
<script>
var score = 0;
function scorecounter()
{
score ++;
return score;
}
</script>
答案 0 :(得分:2)
您的score
一开始是因为您在使用
document.write(scorecounter());
这将增加score
的值,然后返回它,从而显示数字1。
您的点击没有增加score
的值的原因是因为您没有再次显示score
。目前,您只是在页面加载时显示分数。然后,当您单击图像时,score
的值会增加,但不会再次显示给DOM(即页面)。要在页面上显示分数的值,可以在要显示分数的元素上使用.innerHTML
。
请参见下面的工作示例:
var score = 0;
function scorecounter() {
score++;
document.getElementById('score').innerHTML = score; // Set the element with the id 'score' to have the value 'score' inside of it. Also note that .innerHTML can be replaced with .textContent to help resolve XSS vulnrabilities.
}
/* css - ignore this */
.red {
background-color: red;
height: 50px;
width: 100%;
color: white;
text-align: center;
cursor: pointer;
}
<p>Score: <span id="score">0</span></p>
<div class='red' onclick="scorecounter()">
Click me (imagine this as your image)
</div>
编辑:正如@BrandonBuck指出的那样,.innerHTML
倾向于跨站点脚本(XSS)。为了避免这种情况,请使用.textContent
而不是.innerHTML
。
答案 1 :(得分:1)
Here is a JSFiddle of it working.
因此,您正在做很多事情,您可能不应该做。这不一定是你的错。 JavaScript很旧,并且在线上有很多资源,其中某些资源注定是不好的。更不用说,我不知道您是从哪里开始的,因此您可能会得到一些非常古老的例子或拥有什么。
那么从哪里开始,让我们看看...我们不再使用document.write
。事实上,大约17年前我开始使用JS时,它并不是那么普遍。 document.write
的问题在于它没有按照您认为的去做。最初解析页面时,将执行该页面,并将编写您告诉它的内容,就是这样。它已经完成工作,并且结束了。直到您重新加载页面,它才会再次写入。
正如@NickParsons在他的评论中指出的那样,您的得分“始于” 1
,因为您在写语句中调用了scorecounter
,因此您正在递增得分并同时写入新值。
接下来,您将使用HTML属性来关联JavaScript操作。由于我们倾向于将JS和HTML保持非常独立,因此在现代Web开发中通常对此并不满意。我将向您展示一些示例。
好的,另一件事是全局值。当然,在您的示例中,这不一定是可以避免的,但是我们可以为此进行一些清理。所以,让我们去吧。首先,让我们清理HTML。除了JS以外,大多数都还不错。
这是我第一次使用javascript。我基本上想创建一个“点击器”游戏。游戏的目标是单击图像以取得积分。我已经尝试过自己修复它并在互联网上查找,但没有发现任何问题。是什么引起了问题?
基本上,每次我打开页面时,分数已经设置为1,但是当我单击图像时分数不会增加。
<div id="bgk">
<div class="layer">
<div class="row p-2">
<div class="col-lg-6 col-xl-6 text-left">
<p>
Score: <span class="score-value"></span>
</p>
</div>
<div class="col-lg-6 col-xl-6 text-right">
<p>
Time: <span class="time-value">2</span>
</p>
</div>
<div class="p-2">
<img src="png.png" id="image">
</div>
</div>
</div>
</div>
因此,除格式化之外,我要做的最大事情就是删除所有JS代码,并将值范围内的类更改为<name>-value
,所以score
是一个非常好的类名,不会误会我的意思-但是score-value
对于我们要放在这里的内容更清楚。
接下来我们要做的就是清理JavaScript。作为基础,这还不错。但这不是我们想要去的地方。让我们逐步进行。我将在这里从头开始,因为我们将对其进行很多更改。第一件事是我们有一个Game
,我们的游戏将有一个与其关联的score
。因此,让我们创建一个类(类语法是新的,但是大多数使用的主要浏览器都支持该类)。
class Game {
constructor() {
this.score = 0;
}
}
Bam。上了我们的课。我们还需要什么?好吧-我们需要增加分数。因此,让我们这样做。
class Game {
constructor() {
this.score = 0;
}
incrementScore() {
this.score += 1;
}
}
足够容易。接下来,我们需要呈现分数,或将其添加到DOM(浏览器处理后的HTML变成“ DOM”或文档对象模型,这是一个让我们进行交互的API以编程方式访问该页面)。
现在,渲染此分数可能是我们游戏的一部分,但事实并非如此-我们的游戏应该仅仅是游戏本身。它实际上不应该包含其他逻辑。否则,我们将获得超类,并且我们可能还没有尝试这样做。但是我们可以创建一个新的类...称之为UserInterface
,因为您知道,这是我们的UserInterface
。大多数JavaScript库会将应用程序的HTML / DOM方面称为“视图”或“组件”。我使用的是“用户界面”,因为我们是在谈论“游戏”,而通用术语是UI。
class UserInterface {}
好的,所以我们需要渲染文本。为此,我们需要获取要存储分数的DOM节点,然后我们需要将其文本设置为当前分数。 UserInterface不知道得分是多少,游戏知道,所以我们需要传递一些数据。
class UserInterface {
renderScore(score) {
const el = document.querySelector('.score-value');
el.textContent = score;
}
}
您看到我用过const
。在大多数情况下,您可以想象const
像var
一样-它声明了一个变量。在下面,它们的工作方式完全不同。在不深入探讨JavaScript变量作用域的情况下,我只想说var
是老派,而const
是新派。 const
不仅定义了像var
这样的变量,而且还定义了它,使得它不能被重新分配。由于我们从未在el
的正文中重新分配renderScore
,因此我将其设置为const
。现在,var
是我所说的旧学校,而它的新学校选择是let
,它的作用与const
差不多(就范围而言),但允许您重新分配价值。我鼓励您进一步研究为什么添加let
和const
,但这超出了答案。
这里有一个优化-每次我渲染时,我都会搜索.score-value
元素。这是不好的。我可以在这里采取几种方法,但是为了简单起见,让我们最简单地进行一下准备。
class UserInterface {
constructor() {
this.scoreValueEl = document.querySelector('.score-value');
}
renderScore(score) {
this.scoreValueEl.textContent = score;
}
}
顺便说一句,您可能不知道document.querySelector
的作用,但是您可以将其视为在DOM(同样,在浏览器对其进行处理后HTML页面变成什么)中搜索与文本匹配的元素你传递给它。术语selector
来自CSS,您可以在CSS中通过“选择”元素来定义规则。您可以按标签h3
,div
等进行选择。也可以按类名进行选择(只需在类名前面附加一个.
,例如.score-value
class="score-value"
元素),也可以按ID进行选择(只需在类名后面附加一个类似于#
的{{1}})即可。您可能会变得更加复杂,但现在就不要说了。所以.
说,“嘿DOM,您能找到上面带有“得分值”类的元素并将其还给我吗?”
好的,所以现在我有了Game来跟踪得分(以及其他将来的游戏元素),然后有了User Interface来将这些内容呈现给用户。接下来,我们需要进行一些交互。这部分可能是传递许多函数等的主题。因此,我将使其保持相对简单。准备好Game和UserInterface类后,我们将点击绑定到我们的图像上并增加分数并进行渲染。因此,让我们放手一搏。首先,让我们创建新值:
document.querySelector('.score-value')
好吧,所以第一部分。现在让我们处理点击。再次使用const game = new Game();
const ui = new UserInterface();
// we want to show the score on load, so let's do that
ui.renderScore(game.score);
来获取图像:
document.querySelector
好的,这里有两件事。 // see here, we only have one img tag on the page, so I use the tag
// as the selector to find it
const img = document.querySelector('img');
img.addEventListener('click', () => {
game.incrementScore();
ui.renderScore(game.score);
});
是JS表示“嘿元素,当用户执行X做Y时”的方式,在这种情况下,我们说“当用户单击此图像时,运行此功能”。因此,我们传递给addEventListener
的第一个值是我们要处理的事件的名称,第二个值是我们要在触发事件时执行的函数。现在,该函数以“箭头函数”形式编写,它是简写形式,与addEventListener
的含义相同。所以function() {}
与() => {}
是同一件事(同样,我掩盖了一些差异,因为它超出了此答案的范围,您肯定应该查找这些差异)。因此,不要被其中的箭头功能惊慌,它是我们传递给调用的简单JS函数。请注意,在此函数内部,我们先增加分数,然后将其呈现。
所以最终的JS应该是这样的:
function() {}
Here is a JSFiddle of it working.
添加
(是的,我还有更多话要说)
话虽如此,学习JS很容易且容易上手。如果您想复习或学习新知识,可以前往CodeAcademy,或者如果您不介意自费一些SkillShare,PluralSight,CodeSchool等提供JavaScript课程。
除了学习有关JavaScript的更多信息外,大多数现实世界中的JavaScript都是以某种框架为起点编写的。提到了Vue,因此当您觉得自己有了JS的知识和舒适度时,就应该研究Vue。很棒是因为它具有最少的样板(“入门”所需的代码量),并且从本质上讲,与其他流行的解决方案具有同等的功能。其他解决方案包括React,Angular,也许Ember仍然存在,Meteor(用于完整堆栈的东西)等等。同样,尽管随着越来越多的人离开它,jQuery正在“走出困境”,但jQuery仍然存在,并且仍然提供了大量便利,而不是直接与DOM一起使用。所以总是有这条路线。
JavaScript的世界很大,并且还在不断发展。因此,您可以真正找到满足其目的的任何产品。有成百上千的MVC框架,组件框架,DOM包装器,其他基本utils,游戏引擎等等。