---
# System prepended metadata

title: 新手 JS 地下城-1F 9x9 乘法表
tags: [JS地下城]

---

# 新手 JS 地下城-1F 9x9 乘法表
###### tags: `JS地下城`

## 思路歷程

1. 先利用for迴圈把 1~9 x 1~9這件事情搞定
2. 再來想怎樣建立出九張卡片，把九份計算結果分別丟進去

## 過程

### 1. 先利用for迴圈把 1~9 x 1~9這件事情搞定

由於這是一個有重複性質的卡片組合，所以我希望能直接用`js`將`html`組合好再印出，就先創了一個空的`div`，並下了一個`id=wrapper`。

```htmlmixed=
<div id="wrapper">
</div>
```
這將成為之後卡片們的家。

之後我先來驗證一下我寫的for迴圈，是否能正確計算出9x9 乘法表的結果。
```javascript=
for (var i = 1; i <= 9; i++) {
  for (var a = 1; a <= 9; a++) {
    console.log(i * a);
  }
}
```
到這邊9x9 乘法表的for迴圈骨架可以說是完成了，接下來要試著組合html。

### 2. 再來想怎樣建立出九張卡片，把九份計算結果分別丟進去

建立九張卡片的工作，會在第一層for迴圈中執行，卡片的內容，則會在第二層for迴圈建立。

為了先看清楚html架構，我先直接在html上切出外觀。

```htmlmixed=
<div id="wrapper">
  <div class="container">
    <div class="row">
      <div class="col-4">
        <div class="card">
          <p>2 x 1 = 2</p>
          <p>2 x 2 = 4</p>
          <p>2 x 3 = 6</p>
        </div>
      </div>
    </div>
  </div>
</div>
```

因為主要是在練習JS邏輯，所以切版的部分就用BS偷懶一下。

為了要讓html乾淨，也為了要順便練習用js創建DOM元素，所以除了最外層的`<div id="wrapper">`之外，其餘我都打算用js創出來

```javascript=
var el = document.getElementById('wrapper');
//先找到最外層容器
var createDiv = document.createElement('div');
//第一層div
var createDiv2 = document.createElement('div');
//第二層div
createDiv.classList.add("container");
//創建div並增加class＝"container"
el.appendChild(createDiv);
//塞到最外層容器中
createDiv2.classList.add("row");
//創建第二個div並增加class＝"row"
createDiv.appendChild(createDiv2);
//塞到第一個div中
```

切到html去看
```
```

架出html架構之後，就來拆成js分片如下：
```javascript=
var cardEl = `<div class="col-4"><div class="card">${cardContent}</div></div>`;
//卡片
var cardContent = `<p>${i} x ${a} = ${i*a}</p>`;
//卡片的內容物
```

剛說到卡片要在第一層for迴圈製造，卡片內容要在第二層for迴圈製造，所以我姑且先把他們移進去。

```javascript=
for (var i = 1; i <= 9; i++) {
  for (var a = 1; a <= 9; a++) {
    var cardContent = `<p>${i} x ${a} = ${i * a}</p>`;
    //卡片的內容物
  }
  var cardEl = `<div class="col-4"><div class="card">${cardContent}</div></div>`;
  console.log(cardEl);
}
```

組起來之後用console看一下，會發現出現9次以下結果：
```htmlmixed=
<div class='col-4'>
    <div class='card'>
        <p>1 x 9 = 9</p>
    </div>
</div>
````

其中1 x 9 = 9的 1的部分，其實9次就有9個數字，但我只拿一個當分析。

從這個結果可以看出他在`${cardContent}`的時候，只會顯示出最後一筆的資料，所以我們必須有個讓他可以將結果累加顯示的設定。

首先先設定一個空的字串
```javascript=!
var str ='';
```

然後把cardContent的內容在str中累加起來
```javascript=!
str += cardContent;
```

最後把填空的變數換成str
```javascript=!
  var cardEl = `<div class="col-4"><div class="card">${str}</div></div>`;
```

用console看一下組出來的結果：
```htmlmixed=
<div class='col-4'>
    <div class='card'>
        <p>1 x 1 = 1</p>
        <p>1 x 2 = 2</p>
        <p>1 x 3 = 3</p>
        <p>1 x 4 = 4</p>
        <p>1 x 5 = 5</p>
        <p>1 x 6 = 6</p>
        <p>1 x 7 = 7</p>
        <p>1 x 8 = 8</p>
        <p>1 x 9 = 9</p>
    </div>
</div>
```

看來是成功了，最後就是要把這個組好的HTML塞到卡片中，並且顯示在HTML上面

```javascript=
var el = document.getElementById("wrapper");
//先找到最外層容器
var createDiv = document.createElement("div");
//第一層div
var createDiv2 = document.createElement("div");
//第二層div
createDiv.classList.add("container");
//創建div並增加class＝"container"
el.appendChild(createDiv);
//塞到最外層容器中
createDiv2.classList.add("row");
//創建第二個div並增加class＝"row"
createDiv.appendChild(createDiv2);
//塞到第一個div中

for (var i = 1; i <= 9; i++) {
  var str = "";
  for (var a = 1; a <= 9; a++) {
    var cardContent = `<p>${i} x ${a} = ${i * a}</p>`;
    str += cardContent;
    //卡片的內容物
  }
    var cardEl = `<div class="col-4"><div class="card">${str}</div></div>`;
    createDiv2.innerHTML = cardEl;
}

```
在寫這個的時候發現，`document.createElement("div")`當他被定義在變數中的時候，那個變數創出來的物件會變成可以被指定的狀態。
例如我創了
```javascript=!
var createDiv = document.createElement("div")
```
程式會在記憶體中做好一個`<div></div>`，我想在這個div上面加class，只需要對變數下classList.add就好，

```javascript=!
createDiv.classList.add("container");
```

差不多寫到這裡，用innerHTML要印出來的時候，會發現只顯示出最後一筆，因為innerHTML有覆寫的特性，他就像是先把1 x 1 ~ 1 x 9組完印出來之後，又把他用剛組完的2 x 1 ~ 2 x 9覆蓋掉，所以最後只會剩9 x 1 ~ 9 x 9的組合在畫面上。

```
9 x 1 = 9
9 x 2 = 18
9 x 3 = 27
9 x 4 = 36
9 x 5 = 45
9 x 6 = 54
9 x 7 = 63
9 x 8 = 72
9 x 9 = 81
```

這邊有幾種方法可以處理，第一是把9張卡片也先用一個空字串組好，再塞進createDiv2這塊div中，或是用createElement，讓他在第一層for迴圈中被製造+塞資料七次。

為了要嘗試不同的寫法，我這邊用了createElement的方式去寫

```javascript=
  var cardEl = `<div class="card">${str}</div>`;
  var createDiv3 = document.createElement("div");
  createDiv3.classList.add("col-4");
  createDiv3.innerHTML = cardEl;
  createDiv2.appendChild(createDiv3);
```

## 完整程式碼如下：
```javascript=
var el = document.getElementById("wrapper");
var createDiv = document.createElement("div");
var createDiv2 = document.createElement("div");
createDiv.classList.add("container");
el.appendChild(createDiv);
createDiv2.classList.add("row");
createDiv.appendChild(createDiv2);

for (var i = 1; i <= 9; i++) {
  var str = "";
  for (var a = 1; a <= 9; a++) {
    var cardContent = `<p>${i} x ${a} = ${i * a}</p>`;
    str += cardContent;
  }
  var cardEl = `<div class="card">${str}</div>`;
  var createDiv3 = document.createElement("div");
  createDiv3.classList.add("col-4");
  createDiv3.innerHTML = cardEl;
  createDiv2.appendChild(createDiv3);
}

```


## codepen

<iframe height="265" style="width: 100%;" scrolling="no" title="9x9乘法表" src="https://codepen.io/joy-cheng/embed/BapmBWg?height=265&theme-id=dark&default-tab=result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href='https://codepen.io/joy-cheng/pen/BapmBWg'>9x9乘法表</a> by Joy Cheng
  (<a href='https://codepen.io/joy-cheng'>@joy-cheng</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>