前端JQuery應用實戰筆記 4 - JSON 資料格式 (上)

什麼是JSON

一般網頁設計通常都會包含資料,資料維護比較不容易。透過 JSON 和 XML 就可以將網真結構(HTML)與資料(Data)完全分開,會更容易維護。而 JSON(JavaScript Object Notation,JavaScript物件表示法)是一種輕量級的資料交換語言,該語言以易於讓人閱讀的文字為基礎,用來傳輸由屬性值或者序列性的值組成的資料物件。
簡易來說就是的陣列物件

**JSON 無法直接載入 HTML , 必須透過 Javascript 載入**

JSON 應用在哪些地方

  • 前端與後端的溝通介面
  • 製作好介面,前後端可同時進行開發工作
  • 前端撰寫好相關程式,改指向後端所提供 API 路徑即可

JSON 資料結構語法

JSON 資料結構語法網址

JSON 與 XML格式比較

  • 在相同資料內容情況下,JSON 文字字數比較少,XML 字數相對比較多。
  • 目前使用 JSON 資料交換格式已經大幅領先 XML 資料交換格式。

練習

ex.1 訊息公告-JSON 字串

利用Javascript讀取JSON資料檔案,並顯示於HTML上。

ex.1 練習

index.html

1
2
3
<body>
<div id="message"></div>
</body>

message.json

1
"讀取JSON檔案資料,文字目前顯示網頁正在維護中。請之後再重試!"

all.js

1
2
3
4
5
$(function () {
$.getJSON("message.json", function (data) {
$("#message").html(data);
});
});
  • $.getJSON 來獲取 JSON 檔案
  • $().html 用來設置 inner HTML

JSON 資料型態有四種:

  • 字串 ( String )
  • 數字 ( Number )
  • 布林值 ( Boolean )
  • 空值 ( null )

JSON 中的資料格式無法使用:

  • 末定義 ( undefined )
  • 函式 ( function )
  • 正规式 ( regular expression )

JSON 一定要用雙引號,不能用單引號


ex.2 相簿-JSON陣列

將相片連結放在JSON,再利用Javascript去讀取,資料與畫面分開處理。

ex.2 練習

index.html

1
2
3
<div class="photo">
<img height="100%" id="image" />
</div>

photos.json

1
2
3
4
5
6
7
8
[
"images/img1.jpg",
"images/img2.jpg",
"images/img3.jpg",
"images/img4.jpg"
]

// 陣列 (Array) 顯示符號 [] (中括號)

all.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(function() {
$.getJSON("photos.json", function(data) {
var i = 0; //索引數
function run() {
if (i >= data.length) { //循環判斷
i = 0;
}
$("#image").attr("src", data[i]); //插入JSON連結內容
i++;
}
setInterval(run, 3000); //每3秒定時呼叫
run(); //先執行一次,開頭才不會沒內容
});
});
  • $.getJSON 讀入 JSON 資料到 data 裡
  • 判斷 data 總共有幾筆資料,並將資料印入 HTML
  • setInterval(run, 3000); 每3秒定時呼叫 run 函式
  • run(); 先執行一次,開頭才不會沒內容
  • JSON 資料集合有兩種 : 陣列 ( Array ) / 物件 ( Object )
  • 定時呼叫使用 setlnterval 方法,每間隔呼叫。
  • 延遲呼叫使用 setTimeout 方法,只呼叫一次。

ex.3 相簿切換效果和文字說明-JSON巢狀陣列

延續上個練習,將JSON資料做巢狀陣列,圖片配合文字一起使用。
ex.3 練習

index.html

1
2
3
4
<div class="photo">
<img height="100%" id="image" />
</div>
<div id="text"></div>

photos.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
[
"../images/img1.jpg",
"第一張,圖片說明文章。"
],
[
"../images/img2.jpg",
"第二張,圖片說明文章。"
],
[
"../images/img3.jpg",
"第三張,圖片說明文章。"
]
]

all.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$(function() {
$.getJSON("photos.json", function(data) {
var i = 0;
function run() {
if (i >= data.length) {
i = 0;
}
$("#image").fadeOut(function() { //替圖片做淡入淡出動畫效果
$(this).attr("src", data[i][0]).fadeIn();
$("#text").text(data[i][1]);
i++;
});
}
setInterval(run, 3000);
run();
});
});

要把 i++ 搬入 $(“#image”).fadeOut 的 function 裡面,不然一開始執行程式,i 會自動 +1 開始計算,這樣就不會從第一張開始,到時循環會出錯。

  • data[i][0]~data[i][1] 選擇JSON資料裡的子項目,用兩個並列中括號顯示。
  • fadeIn() / fadeOut() 也算是非同步

ex.4 輪播廣告燈箱-JSON 巢狀陣列

延續輪播練習,將JSON資料做巢狀陣列,圖片配合連結一起使用,並由右往左循環輪播。
ex.4 練習

index.html

1
2
3
<div class="scrollable">
<div class="inbox"></div>
</div>

data.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
[
"../images/img1.jpg",
"http://www.google.com.tw"
],
[
"../images/img2.jpg",
"http://www.yahoo.com.tw"
],
[
"../images/img3.jpg",
"http://www.facebook.com"
]
]

all.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
25
26
27
28
29
$(function () {
$.getJSON("data.json", function (data) {
var html = "";
//開始跑迴圈將json資料跑出來放在html變數裡
for (var i = 0; i < data.length; i++) {
html += "<div>";
html += "<a href=\"" + data[i][1] + "\" target=\"_blank\"><img src=\"" + data[i][0] + "\"></a>";
html += "</div>";
}
$(".inbox").html(html); //印出html
$(".inbox>div").first().clone().appendTo($(".inbox")); //複製第一張圖片到最後面去
var index = 0; //放入計算的索引值
function run() {
$(".inbox").animate({ left: "-=500" }, function () {
if (index >= data.length - 1) {
index = -1;
$(this).css("left", 0);
}
index++;
});
}
var sid = setInterval(run, 2000); //設定定時器
$(".inbox").hover(function () {
clearInterval(sid);
}, function () {
sid = setInterval(run, 2000);
});
});
});

圖片循環輪播方式,在整列圖片最後方複製第一張圖片,跟著輪放,等到放最後一張(也就是複製的第一張),在馬上切換到原始的一張,因為都是同一張照片,切換視覺會看不出來,就可以一直重複播放了。

$(".inbox>div").first().clone().appendTo($(".inbox"));

  • $(“.inbox>div”).first().clone() 程式先把第一張圖片複製
  • .appendTo($(“.inbox”) 再把複製的第一張圖放到最後面去

$(".inbox").animate({ left: "-=500" }

  • .animate() 使用動畫來位移
  • -=500 事先讀取本身目前位置 0 然後在 -500。

if (index >= data.length - 1)
假如索引數如果大於等於資料的最後一筆-1 (也就是倒數第二筆)。

index = -1; index++;
函式裡就會改成 -1 ,因後面執行 index++ 會自動再加一筆,索引數就會變 -1+1 = 0,就會回到第一張。

var sid = setInterval(run, 2000);
設定定時器,放入 sid 變數,並記住當下索引編號的照片。

$(".inbox").hover(function () {clearInterval(sid);}, function () {sid = setInterval(run, 2000);});
當滑鼠移動到照片,定時器會清除停止目前索引的照片,而滑出時,重新啟動定時器,並把目前索引編號加回,這樣照片輪播才能延續。

  • setIlntervalsetTimeout 方法執行後會回傳一個編號,
    可利用這編號傳入 clearlntervalclearTimtout 方法,則可以取消執行。

  • \" 在碰到需要單純輸出雙引號又碰到字串頭尾錯誤時,可在雙引號前面加入\使用。

  • 轉義字元表示在字串中包含特殊字元,以下為常用轉義字元 :

    字元意義字元意義
    \b後退一格\v垂直Tab
    \f換頁\'單引號
    \n換行\"雙引號
    \r歸位\\反斜線()
    \tTab\uXXXXUnicode字元 ex:\u08K1

ex.5 輪播廣告燈箱控制元件-JSON巢狀陣列

上一例輪播的加強版,增加前後箭頭及張數點選擇的圓點。
ex.5 練習

index.html 增加前後箭頭及圓點標籤,並外加一層整個包住。

1
2
3
4
5
6
7
8
<div class="outbox">
<div class="scrollable">
<div class="inbox"></div>
</div>
<div class="navi"></div>
<div class="prev"></div>
<div class="next"></div>
</div>

data.json 同上一例。

all.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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
$(function () {
$.getJSON("data.json", function (data) {
var html = "";
var navi = ""; //宣告空的圓點變數
for (var i = 0; i < data.length; i++) {
html += "<div>";
html += "<a href=\"" + data[i][1] + "\" target=\"_blank\"><img src=\"" + data[i][0] + "\"></a>";
html += "</div>"
navi += "<span"; // 加入圓點
// 判斷是否為第一個圓點,加上active
if (i == 0) {
navi += " class=\"active\"";
}
navi += "></span>";
}
$(".inbox").html(html);
$(".navi").html(navi); //寫入html裡的navi
$(".inbox>div").first().clone().appendTo($(".inbox"));
var index = 0;
//Next往後往下一張跑照片
function run() {
if ($(".inbox").is(":animated")) return;
$(".inbox").animate({ left: "-=500" }, function () {
if (index >= data.length - 1) {
index = -1;
$(this).css("left", 0);
}
index++;
dot();
});
}
//Prev往前往上一張跑照片
function back() {
if ($(".inbox").is(":animated")) return;
//拉出animate外執行,確保數值計算正確回到第一張
if (index <= 0) {
index = data.length;
$(".inbox").css("left", index * -500);
}
$(".inbox").animate({ left: "+=500" }, function () { //改+數才能往右移動
index--; //遞減
dot();
});
}

var sid = setInterval(run, 2000); //設定定時器
$(".inbox,.navi,.next,.prev").hover(function () { //增加移停選項
clearInterval(sid);
}, function () {
sid = setInterval(run, 2000);
});
//增加圓點函式
function dot() {
$(".navi>span.active").removeClass();
$(".navi>span").eq(index).addClass("active");
}
//點擊部分
$(".next").click(run);
$(".prev").click(back);
$(".navi>span").click(function () {
index = $(this).index(); //宣告變數為目前點擊的索引數
$(".inbox").animate({ left: index * -500 }, dot); //點擊圓點移動並執行更換已選到的黑點
});
});
});

if (i == 0) { navi += " class=\"active\""; }
一開始用來判斷第一個圓點加上 active 的標籤 (為選取狀態)。
if ($(".inbox").is(":animated")) return;
在兩個 run 、 back 兩個函式加入,目的是判斷目前是否為 :animated (持續動作) 狀態,如果是就停止動作,因為如果一直按很多次,程式就會執行很多次,就算移到別的地方動作,還是會先執行完才會做其他動作,所以加入此語法,可以馬上取消動作進而執行其他動作。
$(".navi>span").eq(index).addClass("active");
跳到索引數的 span 加上 active 的標籤 (為選取狀態)。

  • index 方法可以取得目前選取器在同層中的索引數。
  • eq 方法可以從選取器篩選出第 n 個内容 ( n 從 0 開始 )
  • .eq(0)、eq(“”) 等同於 .first() 方法
  • .eq(-1) 等同於 .last() 方法。