第一次在无法正常运作的Clicker游戏中使用JavaScript

时间:2018-10-20 09:11:56

标签: javascript html

这是我第一次使用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>

2 个答案:

答案 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。在大多数情况下,您可以想象constvar一样-它声明了一个变量。在下面,它们的工作方式完全不同。在不深入探讨JavaScript变量作用域的情况下,我只想说var是老派,而const是新派。 const不仅定义了像var这样的变量,而且还定义了它,使得它不能被重新分配。由于我们从未在el的正文中重新分配renderScore,因此我将其设置为const。现在,var是我所说的旧学校,而它的新学校选择是let,它的作用与const差不多(就范围而言),但允许您重新分配价值。我鼓励您进一步研究为什么添加letconst,但这超出了答案。

这里有一个优化-每次我渲染时,我都会搜索.score-value元素。这是不好的。我可以在这里采取几种方法,但是为了简单起见,让我们最简单地进行一下准备。

class UserInterface {
  constructor() {
    this.scoreValueEl = document.querySelector('.score-value');
  }

  renderScore(score) {
    this.scoreValueEl.textContent = score;
  }
}

顺便说一句,您可能不知道document.querySelector的作用,但是您可以将其视为在DOM(同样,在浏览器对其进行处理后HTML页面变成什么)中搜索与文本匹配的元素你传递给它。术语selector来自CSS,您可以在CSS中通过“选择”元素来定义规则。您可以按标签h3div等进行选择。也可以按类名进行选择(只需在类名前面附加一个.,例如.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,游戏引擎等等。