innerHTML 與 for 運用

當我想要「撈出我要的資料」,並且渲染到網頁上,該怎麼做呢?

html:

🎃 <ul></ul>裡面是「空值」

1
2
3
4
<h1>每個農場的“農夫名字”</h1>
<ul class="list">

</ul>

JS:

🎃 farms陣列中,有兩個物件(兩個農場)

1
2
3
4
5
6
7
8
9
10
var farms = [
{
farmer: '卡斯伯',
dogs: ['張姆士', '龐的']
},
{
farmer: '查理',
dogs: ['皮皮']
}
];

我現在要做的是:「從farms陣列中,依序撈出“農夫的名字”」,並渲染到網頁上

作法如下

🎃 先建立變數el,用來選取'.list
var el = document.querySelector('.list');

🎃 建立變數farmLen,來計算出「陣列中,共有幾筆資料」:
var farmLen = farms.length;

🎃 建立變數,先給它「空的字串」(後面會用到):
var str = '';

JS:

1
2
3
4
5
var el = document.querySelector('.list');

var farmLen = farms.length;

var str = '';

for迴圈

在「for迴圈」裡面:

🎃 建立變數content,來插入內容:

var content = '<li>'+ farms[i].farmer +'</li>';

🍋 <li></li>裡面,依序帶入「農夫名字」: farms[i].farmer

🎃 把「變數content」放入.list裡面:

❌ 錯誤寫法:直接用el.innerHTML = content;

1
2
3
4
for(var i=0; i<farmLen; i++){
var content = '<li>'+ farms[i].farmer +'</li>';
el.innerHTML = content;
};

😢 這樣是錯誤的:只有出現「第二個農夫的名字」:查理

🍋 只有出現「第二個農夫的名字」,原因為:

雖然,變數content的確有跑兩次迴圈(第一個 & 第二個農夫的名字),但是 .innerHTML在帶入「第一個農夫名字」後,要帶入「第二個農夫名字」前,會先把「第一個農夫名字」給清除掉(這是.innerHTML的特性),所以,最後結果就只會出現「第二個農夫的名字」

.innerHTML的特性:會先把「原本的資料都清除」之後,再帶入「新的資料」

✅ 正確寫法

🎃 用「變數str」來「累加字串」: str+=content;

🍋 「變數str」原本是「空的字串」,使用+=來依序加入「兩筆變數content的字串」

🍋 用console.log()來看「變數str」跑出的結果:

  • 跑第一次迴圈時,印出變數content的「第一筆」資料
  • 跑第二次迴圈時,印出變數content的「第一筆+第二筆」資料

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var farms = [
{
farmer: '卡斯伯',
dogs: ['張姆士', '龐的']
},
{
farmer: '查理',
dogs: ['皮皮']
}
];

var el = document.querySelector('.list');

var farmLen = farms.length;

var str = '';

for(var i=0; i<farmLen; i++){
var content = '<li>'+ farms[i].farmer +'</li>';
str+=content;
console.log(str);
};

.innerHTML

🎃 跑完「for迴圈」後,「變數str」已經將「兩筆字串」都記錄起來了。現在,就可以插入到.list裡面了: el.innerHTML = str;

‼️ 這裡的el.innerHTML = str;不用寫在「for迴圈裡面」,是因為:

🍋 跑完for迴圈後,「變數str」已經把「第一筆+第二筆」資料都記錄起來了(下圖的紅色箭頭處)

✅ 所以,在把「變數str」掛到.list上時,就不需要再跑「for迴圈」了,寫在「for迴圈」的外面即可

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var farms = [
{
farmer: '卡斯伯',
dogs: ['張姆士', '龐的']
},
{
farmer: '查理',
dogs: ['皮皮']
}
];

var el = document.querySelector('.list');

var farmLen = farms.length;

var str = '';

for(var i=0; i<farmLen; i++){
var content = '<li>'+ farms[i].farmer +'</li>';
str+=content;
console.log(str);
};

el.innerHTML = str;

😄 網頁上就會依序出現「兩個農夫的名字」了

完整 JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var farms = [
{
farmer: '卡斯伯',
dogs: ['張姆士', '龐的']
},
{
farmer: '查理',
dogs: ['皮皮']
}
];

var el = document.querySelector('.list');

var farmLen = farms.length;

var str = '';

for(var i=0; i<farmLen; i++){
var content = '<li>'+ farms[i].farmer +'</li>';
str+=content;
console.log(str);
};

el.innerHTML = str;

要把「變數var str = '';」建立在「for迴圈“外面”」

我的 jsbin 範例

https://jsbin.com/peyigaq/edit?html,console,output

html:

1
2
<h1>每個農場的“農夫名字”</h1>
<ul class="list"></ul>

❌ JS 錯誤寫法

❌ JS 錯誤寫法:把「變數var str = '';」建立在「for迴圈“裡面”」

JS 這樣寫,會導致:插入到<ul></ul>裡面的,就只有<li>查理</li>而已

原因為:
1️⃣ 跑第一次「for迴圈」時–>

  • 「變數str」原本是「空的字串」
  • 「變數str」+= <li>卡斯伯</li>

2️⃣ 跑第二次「for迴圈」時–>

  • 「變數str」又變回「空的字串」(因為又再跑了一次var str = '';
  • 「變數str」+= <li>查理</li>

😢 因此,跑完兩次「for迴圈」後,最後在console.log(str);看到的結果–>
「變數str」就只有<li>查理</li>而已

😢 因此,用.innerHTML插入到<ul></ul>裡面的,就只有<li>查理</li>而已

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var farms = [
{
farmer: '卡斯伯',
dogs: ['張姆士', '龐的']
},
{
farmer: '查理',
dogs: ['皮皮']
}
];

var el = document.querySelector('.list');

var farmsLen = farms.length;

for(var i=0; i<farmsLen; i++){
var str = '';
str += '<li>'+ farms[i].farmer +'</li>';
console.log(str);
};

el.innerHTML = str;

✅ JS 正確寫法

✅ JS 正確寫法:把「變數var str = '';」建立在「for迴圈“外面”」

JS 這樣寫:插入到<ul></ul>裡面的,就會是<li>卡斯伯</li><li>查理</li>

原因為:
🍋 「變數str」原本是「空的字串」 var str = '';

1️⃣ 跑第一次「for迴圈」時–>

  • 「變數str」 += <li>卡斯伯</li>

2️⃣ 跑第二次「for迴圈」時–>

  • 「變數str」這時候是 <li>卡斯伯</li>
  • 「變數str」 又再 += <li>查理</li>

😄 因此,跑完兩次「for迴圈」後,最後在console.log(str);看到的結果–>
「變數str」會是<li>卡斯伯</li><li>查理</li>

😄 因此,用.innerHTML插入到<ul></ul>裡面的,就會是<li>卡斯伯</li><li>查理</li>

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var farms = [
{
farmer: '卡斯伯',
dogs: ['張姆士', '龐的']
},
{
farmer: '查理',
dogs: ['皮皮']
}
];

var el = document.querySelector('.list');

var farmsLen = farms.length;

var str = '';

for(var i=0; i<farmsLen; i++){

str += '<li>'+ farms[i].farmer +'</li>';
console.log(str);
};

el.innerHTML = str;

.innerHTML.createElement的差異

🎃 用.innerHTML來操控 html

🍋 步驟一:先組好「整個字串」

例如:

1
str = '<li>卡斯伯</li><li>查理</li>';

🍋 步驟二:再讓瀏覽器自己去編譯出「<li></li>和裡面的文字內容」

1
el.innerHTML = str;

‼️ .innerHTML的特性:

會先把「原本的資料全部清除」之後,再帶入「新的資料」

🎃 用.createElement來操控 html

🍋 步驟一:先在 JavaScript 生成一個「<li></li>元素」

🍋 步驟二:在這個「<li></li>元素」上,我可以做各種事情(例如:加入文字內容、改變文字顏色)

🍋 步驟三:最終再來決定,我要把這個「<li></li>元素」塞在哪個「節點」上,例如:我要把「<li></li>元素」用.appendChild塞在<ul></ul>裡面

‼️ .appendChild的特性:

用「.appendChild動態新增子節點」到節點上,會在「原本的資料“後面”」去做新增

✔️ 「原本的資料」全部都會保留著