一、說明
「互動式網頁」概念由來已久,但實作的的方式一直不斷更新,如javascript, Java applet, flash, css等。其中Javscript支援度高、應用廣、學習容易,很不錯的語言。
- 在此透過jQuery來使用Javascript, AJAX
- 本文中採用Google Chrome瀏覽器及其開發人員工具
二、主要應用
- 選擇器(Selector)
- DOM控制
- 結構
- 事件
- 資料處理
- AJAX
三、練習模版
3.1 增加路徑常數
打開檔案
application/config/constants.php加入設定
1
2
3
4
5
6/**
* System Path
*/
define('ASSETS', '/assets/');
define('CSS_DIR', ASSETS . 'css/');
define('JS_DIR', ASSETS . 'js/');建立資料夾
assets/js/
assets/css/
3.2 建立Controller
新增檔案
application/controllers/Js_training.php寫入內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
defined('BASEPATH') or exit('No direct script access allowed');
class Js_training extends CI_Controller
{
/**
* Index Page for this controller.
*/
public function index()
{
$this->load->view('jsTraining');
}
}
3.3 建立View
新增檔案
application/views/jsTraining.php以此為HTML練習模版
寫入內容
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
<html lang="en">
<head>
<title>Bootstrap 4 Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
<script src="/node_modules/jquery/dist/jquery.min.js"></script>
<script src="/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Font Awesome Icon -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" />
<script src="<?= JS_DIR; ?>jsTraining/jsTraining.js"></script>
</head>
<body>
<div class="container">
<!-- Title -->
<div class="row">
<div class="col-sm-12">
<h1>Javascript Training</h1>
<hr>
</div>
</div>
<!-- Controll Form -->
<div class="row">
<div class="col-sm-12"><button class="btn btn-warning float-right ctrl-btn">新增</button></div>
</div>
<!-- Table -->
<div class="row">
<table class="table table-striped table-bordered table-hover ctrl-table">
</table>
</div>
<!-- Message box -->
<div class="row">
<div id="ctrl-message" class="text-danger ctrl-message"></div>
</div>
</div>
</body>
</html>
3.4 建立JS檔
新增檔案
assets/js/jsTraining/jsTraining.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164/**
* 說明:
* <li>1. 頁面函式只會初始化一次
* <li>2. 如果是多頁面組合時,可能被其他頁面呼叫,因此需使用namespane:Page,以方便外部呼叫或試調
*
* 執行順序:
* 1. 註冊$(document).ready()函式,但先不執行
* 2. $(document).ready()之外的程式碼依序執行 - 建構變數、函式obj
* 3. 執行$(document).ready()內註冊的函式
* 4. 確定window.Page是否存在,不存在則初始化
* 5. 執行obj()物件,並將結果存入window.Page[name]
* 6. obj()回傳內容為 new obj.fn.init(options);
* 7. 實例化obj.fn.init(options);並在最後執行函式 _construct(_options);
*/
// IIFE 立即執行函式
(function(window, document, $, undefined) {
// 使用嚴格模式
'use strict';
// DOM下載完後執行
$(document).ready(function() {
// init this page
window.Page = window.Page || new function() {}();
window.Page[name] = obj();
});
// Class Name
var name = '{name}';
// Version
var version = '{version}';
// Default options
var defaults = {};
/**
* *************** Object Build ***************
*/
// Define a local copy of Object
var obj = function(options) {
return new obj.fn.init(options);
};
// Prototype arguments
obj.fn = obj.prototype = {
// Object Name
_name: name,
// Default options
_defaults: defaults,
// AJAX URL
_ajaxUrls: {
list: '/controller_group_forder/controller/ajax',
edit: '/controller_group_forder/controller_edit/ajax',
},
};
/**
* Javascript物件
*/
obj.fn.init = function(options) {
/**
* *************** Object Argument Setting ***************
*/
var self = this;
var _options = options || {};
// Ajax Response - jqXHR(s)
var _jqXHRs;
/**
* *************** 屬性設定 ***************
*/
/**
* *************** 物件必要函式 ***************
*/
/**
* 建構子
*/
var _construct = function() {
console.log('_construct');
_initialize();
};
/**
* 解構子
*/
var _destruct = function() {};
/**
* 初始化
*/
var _initialize = function() {
console.log('_initialize');
/**
* 事件綁定
*/
_evenBind();
};
/**
* 事件綁定
*/
var _evenBind = function() {
console.log('_evenBind');
/**
* 事件 - 增加
*/
/**
* 事件 - 清除規
*/
};
/**
* *************** 功能函式 ***************
*/
/**
* *************** 事件函式 ***************
*/
/**
* 事件 - 送出
*/
var _submit = function(e) {
return this;
};
/**
* 事件 - 清除
*/
var _clear = function(e) {
return this;
};
/**
* 事件 - 增加
*/
var _add = function(e) {
return this;
};
/**
* *************** 私有函式 ***************
*/
/**
* *************** Run Constructor ***************
*/
_construct();
};
// Give the init function the Object prototype for later instantiation
obj.fn.init.prototype = obj.prototype;
// Alias prototype function
$.extend(obj, obj.fn);
})(window, document, $);物件化Javascript模版
3.5 查看結果
- 前往網址:https://crud-training.dev.idv/js_training
練習用頁面建構完成
四、選擇器(jQuery Selector)
使用tag, id, class取得DOM,並讀取物件內容
4.1 使用tag selector
讀取tag:h1內容字串
在函式 _initialize 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | // 讀取tag:h1內容字串 |
- 按F12打開「開發人員工具」,移到console頁籤
- JS翻釋:使用tag選擇器尋找名為h1的元件,並取得元件內容字串
- tag為HTML標籤名稱,參考文件 HTML5 Tutorial
4.2 使用id selector
寫入「測試字串」至id=”ctrl-message”的元件
在函式 _initialize 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | // 寫入「測試字串」至id="ctrl-message"的元件 |
- JS翻釋:使用ID選擇器(#)尋找id為ctrl-message的元件,並將字串「測試字串」寫入元件內容
4.3 使用class selector
變更class=”ctrl-btn”按鈕的元件的顏色為btn-danger
在函式 _initialize 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | // 變更class="ctrl-btn"按鈕的元件的顏色為btn-danger |
- JS翻釋:使用class選擇器(.)尋找含有class為ctrl-btn的元件,並移除class btn-warning、增加class btn-danger
4.4 查看結果
- Selector是極為重要的基礎
- 參考文件:jQuery Selectors
五、DOM控制
5.1 結構
5.1.1 移除按鈕
在函式 _initialize 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | // 移除按鈕 |
- JS翻釋:使用class選擇器(.)尋找含有class為ctrl-btn的元件,並移除該元件
5.1.2 建立表格
在函式 _initialize 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | /** |
參考文件:jQuery Add, jQuery Remove
5.2 事件
5.2.1 按下按鈕時,變更tag:h1文字為「** Javascript Training **」
在函式 _evenBind 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | // 按下按鈕時,變更tag:h1文字為「** Javascript Training **」 |
- JS翻釋:
- 當class為ctrl-btn的元件,在(on)按下click時,執行匿名函式
- 匿名函式:對tag為h1的元件內容改寫為「** Javascript Training **」
5.2.2 偵測滑鼠座標
在函式 _evenBind 中寫入下列程式碼後,按ctrl+F5重整網頁
1 | // 偵測滑鼠座標 |
- JS翻釋:
- 當在整個文件區(document)中偵測到滑鼠移動事件(mousemove)時,執行匿名函式
- 匿名函式:取得事件物件,如果事件物件含有座標資訊,在ctrl-message元件中印出座標資訊
參考文件:jQuery Events
5.3 查看結果
六、AJAX
AJAX即「Asynchronous JavaScript and XML」(非同步的JavaScript與XML技術),使用AJAX執行前後端資料交換有助於減少資料量,非同步特性讓ajax處理時,可同時處理本其他JS程式,讓網頁執行更順暢更多樣化。
AJAX的目的可粗略分為建立(create)、讀取(read)、更新(update)、刪除(delete)。
在此使用RESTFul Style實作ajax前後端資料交換
6.1 修改AJAX server side相關路徑
編輯檔案:assets/js/jsTraining/jsTraining.js
1 | // AJAX URL |
6.2 建立伺服器端接收函式
檔案:application/controllers/Js_training.php
增加下列函式
1 | /** |
6.3 Create
6.3.1 程式碼
- 新增一筆
在函式 _initialize 中寫入下列程式碼後,按ctrl+F5重整網頁1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/**
* 新增一筆
*/
$.ajax({
// 傳送方法
method: 'POST',
// 目標網址
url: self._ajaxUrls.accountApi,
// 傳送資料
data: { name: 'John', location: 'Boston' },
// 回傳資料格式
dataType: 'json',
}).done(function(data) {
// 處理回傳資料 - 印出json字串
$('<div>' + JSON.stringify(data) + '</div>').appendTo($('.ctrl-message'));
// 輸出至console
console.log(data);
}).fail(function (jqXHR) {
// 處理回傳資料
$('<div>' + jqXHR.responseText + '</div>').appendTo($('.ctrl-message'));
console.log(jqXHR);
});示範AJAX Request & Reponse
6.3.2查看結果
6.4 Read
讀取全部
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/**
* 讀取全部
*/
$.ajax({
method: 'GET',
url: self._ajaxUrls.accountApi,
dataType: 'json',
}).done(function(data) {
// 處理回傳資料 - 印出json字串
$('<div>' + JSON.stringify(data) + '</div>').appendTo($('.ctrl-message'));
/**
* 陣列資料配合$.each建立表格
*/
// 建立變數
var tmp, table, thead, tbody, tr, th, td;
// 建立暫存容器
tmp = $('<div></div>');
// 建立thead區塊資料
thead = $('<thead></thead>').appendTo(tmp);
// 建立tbody區塊資料
tbody = $('<tbody></tbody>').appendTo(tmp);
// 建立標題
tr = $('<tr class="bg-info"></tr>').appendTo(thead);
$.each(data.head, function(index, value) {
th = $('<th>'+value+'</th>').appendTo(tr);
});
// 建立內容
$.each(data.data, function(index1, value1) {
tr = $('<tr></tr>').appendTo(tbody);
$.each(value1, function(index2, value2) {
td = $('<td>'+value2+'</td>').appendTo(tr);
});
});
// 取得table元件
table = $('.ctrl-table');
// 將暫存容器內容移至table元件
tmp.children().appendTo(table);
});陣列資料配合$.each建立表格
讀取一筆
1
2
3
4
5
6
7
8
9
10
11
12/**
* 讀取一筆
*/
$.ajax({
method: 'GET',
// 讀取id為3的資料
url: self._ajaxUrls.accountApi + '/3',
dataType: 'json',
}).done(function(data) {
// 處理回傳資料
$('<div>' + JSON.stringify(data) + '</div>').appendTo($('.ctrl-message'));
});
參考文件:$.each()
6.5 Update
- 更新一筆
1
2
3
4
5
6
7
8
9
10
11
12/**
* 更新一筆
*/
$.ajax({
method: 'PUT',
url: self._ajaxUrls.accountApi,
data: { name: 'John', location: 'Boston' },
dataType: 'json',
}).done(function(data) {
// 處理回傳資料
$('<div>' + JSON.stringify(data) + '</div>').appendTo($('.ctrl-message'));
});
6.6 Delete
刪除錯誤 No Delete ID
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* 刪除錯誤 No Delete ID
*/
$.ajax({
method: 'DELETE',
url: self._ajaxUrls.accountApi,
dataType: 'json',
}).done(function(data) {
// 處理回傳資料
$('<div>' + JSON.stringify(data) + '</div>').appendTo($('.ctrl-message'));
}).fail(function (jqXHR) {
// 錯誤處理
$('<div>' + jqXHR.responseText + '</div>').appendTo($('.ctrl-message'));
console.log(jqXHR);
});刪除一筆
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
* 刪除一筆
*/
$.ajax({
method: 'DELETE',
// 刪除id為2的資料
url: self._ajaxUrls.accountApi + '/2',
dataType: 'json',
}).done(function(data) {
// 處理回傳資料
$('<div>' + JSON.stringify(data) + '</div>').appendTo($('.ctrl-message'));
}).fail(function (jqXHR) {
// 錯誤處理
$('<div>' + jqXHR.responseText + '</div>').appendTo($('.ctrl-message'));
console.log(jqXHR);
});
參考文件:
6.7 資料交換要點
- 使用方法POST,GET,PUT,DELETE分別對應新增,讀取,修改,刪除
- 網址格式為:https://host_name/controller_name/function_name/parameter
- 回傳的資料格式為json
- POST,PUT需傳入data屬性,值為要新增/更新的資料
- 使用callback函式done()處理成功回傳的資料
- 使用callback函式fail()處理失敗回傳的資料
- 需定義好從 前端傳到後端 與 後端傳到前端 的資料結構,以免資料處理雜亂
七、參考
7.1 知識
7.2 官網
7.3 教程
未完待續