我怎样才能优化这条长长的"如果"声明?

时间:2016-12-25 02:55:22

标签: javascript html if-statement refactoring

所以,我正在使用Javascript制作一个点击游戏,我遇到了我需要做的很多,而且我在谈论300,if语句。我完成了所有非常繁琐的工作,并开始了我的游戏。

为了向您展示我需要向您展示我的游戏的问题。 所以基本上,每次我点击一个按钮,十个图像中的一个会更新。

IMG1

IMG2

问题是,我为每个数字以及您可以收集的每种材料制作了if语句。

我想知道是否有办法摆脱所有这些if语句,让游戏正常运行,或者有办法优化它。

代码: JSFiddle 大多数代码都是这样的:

if (A == 18) {
    document.getElementById("A1").src = "images/blocks/2A.png";
    document.getElementById("A2").src = "images/blocks/2A.png";
    document.getElementById("A3").src = "images/blocks/2A.png";
    document.getElementById("A4").src = "images/blocks/2A.png";
    document.getElementById("A5").src = "images/blocks/2A.png";
    document.getElementById("A6").src = "images/blocks/2A.png";
    document.getElementById("A7").src = "images/blocks/2A.png";
    document.getElementById("A8").src = "images/blocks/2A.png";
    document.getElementById("A9").src = "images/blocks/1A.png";
    document.getElementById("A10").src = "images/blocks/1A.png";
}

如果您需要实际游戏的链接,请告诉我,因为JSFiddle没有我的照片。

5 个答案:

答案 0 :(得分:1)

您可以使用for循环来设置A + i,但我建议您为具有相同内容的dom设置相同的类。您可以使用getElementsByClass或jQuery选择器,然后批量设置src。

function changeSrc(){
  $(".type1").attr("src", "https://i.stack.imgur.com/zU4NZ.jpg?s=32&g=1");
}
.type1 {display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="type1" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<img class="type1" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<img class="type1" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<img class="type1" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<img class="type1" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<button onclick="changeSrc()">chang src</button>

答案 1 :(得分:1)

如果你使用 jQuery ,你可以尝试这样的事情:

if (A == 18) {
    $('[id^=A]').each(function() {
        $(this).attr("src", "images/blocks/2A.png");
    });

    $("#A9").attr("src", "images/blocks/1A.png");
    $("#A10").attr("src", "images/blocks/1A.png");
}

通过抓取ID为“A”的每个img,然后在结尾添加特定的src属性。

对于两个独特的,它一旦完成就会改变它们。

我知道它并没有完全解决if语句问题,但是,它会大大减少你的代码: - )

答案 2 :(得分:1)

这完全取决于重构后你是什么。你说你有很多If语句,如果这些语句比较同一个变量 A 那么可以使用switch语句,例如:

switch (A)
{
   case 18: 
    document.getElementById("A1").src = "images/blocks/2A.png";
    document.getElementById("A2").src = "images/blocks/2A.png";
    document.getElementById("A3").src = "images/blocks/2A.png";
    document.getElementById("A4").src = "images/blocks/2A.png";
    document.getElementById("A5").src = "images/blocks/2A.png";
    document.getElementById("A6").src = "images/blocks/2A.png";
    document.getElementById("A7").src = "images/blocks/2A.png";
    document.getElementById("A8").src = "images/blocks/2A.png";
    document.getElementById("A9").src = "images/blocks/1A.png";
    document.getElementById("A10").src = "images/blocks/1A.png";
    break;
   case 19: 
    document.getElementById("A1").src = "images/blocks/2A.png";
    document.getElementById("A2").src = "images/blocks/2A.png";
    document.getElementById("A3").src = "images/blocks/2A.png";
    etc...
    break;

   default: 
       document.getElementById("A1").src = "images/blocks/2A.png";
       break;
}

看起来您可能想要创建一个传递elementID的函数,并将图像的字符串作为第二个重构返回。

答案 3 :(得分:1)

如何使用像

这样的规则数组
const rules = [ 
      { rule: 18, imagePaths : [ {A1: "2A.png" }...{A10:    "1A.png" } ]}, 
        { rule: 19 , imagePaths:[....] }          
      ] 

然后根据规则编号,从规则中读取imagePaths并相应地进行设置。即,如果选择的值为18,则从rules数组中获取基于18的规则,然后循环遍历imagePaths并根据规则中的值设置src。

答案 4 :(得分:1)

您拥有的唯一变量是计数器。如果你只记下规则,那么其他一切都可以直接从那个计数器计算出来。

规则是,

部分值A,B和C

您想要创建标记为A,B和C的数字范围,每个范围从0到99,并代表计数器的不同部分,如下所示:

123456
CCBBAA, i.e. A = 56, B = 34, C = 12

  8921
CCBBAA, i.e. A = 21, B = 89, C = 0

这可以通过将数字均分为100并将the remainder(模数)计算为100来完成:

(123456 DIV 100^0) MOD 100 = 56
(123456 DIV 100^1) MOD 100 = 34
(123456 DIV 100^2) MOD 100 = 12

在JS中,可以通过向下舍入来执行整数除法。 Math.floor(140 / 100)不是1.4,而是1. MOD操作由%运算符执行,电源操作由Math.pow()函数执行。所以上面变成了:

Math.floor(123456 / Math.pow(100, 0)) % 100 // = 56
Math.floor(123456 / Math.pow(100, 1)) % 100 // = 34
Math.floor(123456 / Math.pow(100, 2)) % 100 // = 12

这些是直接从您的计数器值派生的A,B和C部分的值。

每个部分十张图像

您想要显示包含10个图像的每个部分。它们的名称范围从“0X”到“10X”,其中“X”是相应的章节字母。

假设分区值为37,您希望前7个图像为“4X”,最后3个为“3X”。

同样,我们可以直接从section值派生图像名称。让我们用整数除法将它分开37并将模数分成3和7:

div = Math.floor(value / 10); // 37 => 3
rem = value % 10; // 37 => 7

现在图像名称取决于我们正在操作的图像。使用0到9的计数器k,我们可以决定图像名称是以4还是3开头。

imageName = (k < rem ? div + 1 : div) + letter;

对于任何小于7的k,我们得到“4X”,另一个得到“3X”。

在代码中,这就是它的全部内容:

var total = 0,
    letters = ['A', 'B', 'C'];

function add() {
  total++;
  showState();
}

function showState() {
  var letter, range, value, imageName, div, rem, i, k;

  for (i = 0; i < 3; i++) {
    letter = letters[i]; // "A", "B", "C"
    range = Math.pow(100, i); // 1, 100, 10000
    value = Math.floor(total / range) % 100; // 0 .. 99

    document.getElementById(letter + "_Check").innerHTML = letter + ": " + value;

    for (k = 0; k < 10; k++) {
      div = Math.floor(value / 10); // 37 => 3
      rem = value % 10; // 37 => 7
      imageName = (k < rem ? div + 1 : div) + letter;
      elem = document.getElementById(letter + (k + 1));
      elem.src = "images/blocks/" + imageName + ".png";
    }
  }
}

这就是您需要的所有代码,而不是复制粘贴的一行。

这是小提琴:https://jsfiddle.net/4kr2xwyq/2/

练习:找出是否可以完全用HTML / CSS替换图像(条形图之类的东西很容易用HTML编写,颜色和元素尺寸可以动态计算和修改)或canvas 。最后这比维护几十个静态图像文件更容易。