標題有點長實在不知道該怎麼下 = =

前言 : 

最近被要求做一個功能,這個功能是這樣子的~~

文章想直接跳到 JSON 操作 請按此,想跳到 離開頁面提示 的請按次

有一個落落長的表單要使用者填寫

然後在使用者離開這個表單的時候要提醒她資料有修改是否要離開?

然後如果她不離開按下儲存按鈕

就要列出有異動的欄位 and 更改的值 (後來只列出欄位不列出值了)

畫面做成像下圖這樣子,感覺像是要簽入原始碼控制般的介面

然後寫入資料庫,紀錄 log + 版本號

Clipboard02

 

然後我就放了一個全域物件來記錄一下異動的資訊

var grobal = grobal || {};

grobal = {

changeTimes: 0,

changeControl: []

}

然後下面監控頁面上欄位的異動

這邊比較有問題的是 textarea,因為textarea 已經換成 ckeditor 所以抓不到 change

要用特別的方法之後再提,不過還是先寫上去

$("input,select,textarea").change(function () {

 

});

然後我每個項目都有自訂txt屬性,去說明欄位是幹嘛的

ex :  <input type="text"  txt="作者">

再來一步一步說明實在太麻煩了,直接把程式片段貼出來好了 @@

/*

紀錄頁面異動全域物件

changeTimes:異動次數,changeControl:異動的陣列實字組

*/

var grobal = grobal || {};

grobal = {

changeTimes: 0

changeControl: []

}

//監控頁面上控制項所有異動 (除ckeditor)

$("input,select,textarea").change(function () {

var val = $(this).attr("txt");

//push 前先移除該項目舊紀錄

removeJArray (grobal.changeControl, "txt", val);

//紀錄異動欄位

grobal.changeControl.push(

{ txt: val }

);

//紀錄異動次數

grobal.changeTimes += 1;

});

//刪除JSON裡面陣列中的某個指定值

function removeJArray (arr,pid, val) {

for (var i = 0; i < arr.length; i++) {

var cur = arr[i];

if (cur[pid] == val) {

arr.splice(i, 1);

break;

}

}

}

然後隨便異動幾個欄位,檢查一下JSON內容

alert(JSON.stringify(grobal));

就會輸出如下圖的JSON

Clipboard02

 

有了異動資料,再來就是使用者要離開前要提示她是否要存檔

就像 gmail 的離開提示,這邊用 beforeunload 事件

$(window).on("beforeunload", function (e) {

e = e || window.event;

if (e) {

e.returnValue = (function () {

if (grobal.changeTimes > 0) {

return "您異動了一些資料,確定不儲存離開?";

}

})();

}

//給chrome + safari用

return (function () {

if (grobal.changeTimes > 0) {

return "您異動了一些資料,確定不儲存離開?";

}

})();

});

然後IE、Chrome的判斷方法不同,所以很蠢的加了兩個幾乎一樣的訊息

這邊有空可以再寫的好一些

邏輯就是如果 grobal 這個全域物件中的 changeTimes 屬性值 > 0

就表示有異動囉

 

再來按下頁面中的存檔按鈕要跳出類似原始碼簽入的dialog 給user 輸入異動原因

前面的 UI 就不貼了,直接看 script

假設我的儲存按鈕是 

<input type="button" class="save" value="儲存">

//按下儲存按鈕,因為我儲存按鈕有兩個,所以用 class="save"

$(".save").click(function () {

//因為儲存會postback,也算是離開頁面

//所以要先解除 beforeunload 事件

$(window).unbind("beforeunload");

var arr = [],str = "",arrlist = grobal.changeControl;

//把grobal.changeControl 中儲存的異動欄位寫到空陣列中

for (var i in arrlist) {

arr.push(arrlist[i].txt);

}

//直接用 .join 串在一起,然後填入前端頁面的容器中

$("#update_fieldmsg").html(arr.join("、"));

$('#signin').modal("show");

return false;

});

 

 就會長的如下圖

 Clipboard02  

 

再來說明一下 ckeditor 要怎麼監控有沒有被異動

ckeditor 有提供 checkDirty 方法來判斷有無異動

checkDirty() 

http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#checkDirty

雖然 on change 也可以監控 (但是要先得到 ckeditor 的 instances)

但是用 change 會有個問題..........使用者每打一個字都被認為是一次 change

但如果每打一個字都要記錄一次異動效能也太差

change 事件比較適合用在計算字數

所以監控異動的話用 checkDirty() 比較適合

下面例子是監控頁面上所有 ckeditor 異動

然後一樣寫到紀錄異動的物件

for (var i in CKEDITOR.instances) {

var ckeditor = CKEDITOR.instances[i];

//判斷ckeditor異動

if (ckeditor.checkDirty()) {

//取得 ckeditor 的名稱,也就是ID

var val = ckeditor.name;

//先移除之前異動紀錄,如果有的話

removeJArray (grobal.changeControl, "txt", val);

//寫入新異動紀錄

grobal.changeControl.push(

{ txt: val }

);

grobal.changeTimes += 1;

}

}

 

再來要記錄幾個比較常用的 JSON 操作方式,有些算是蠻基本的陣列操作

一、首先是最常用的 

JSON.stringify

MDN : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

它可以把你的 JSON 物件轉為 JSON 字串,方便傳輸或利用

ex : 我宣告一個物件實字

var grobal = grobal || {};

grobal = {

changeTimes: 0,

changeControl: []

}

JSON.stringify(grobal ) 就會得到字串

"{"changeTimes":0,"changeControl":[]}"

 

二、如果要新增 JSON 內的陣列元素

push

MDN : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

其實網址內有範例了,不過還是寫一下

如果我要在下面 grobal 物件的 changeControl 陣列中新增元素

grobal = {

changeTimes: 0,

changeControl: []

}

grobal.changeControl.push(

{ "control" : "cname" }

);

結果就會變成這樣

"{"changeTimes":0,"changeControl":[{ "control" : "cname" }]}"

 

三、刪除 JSON 內指定元素

delete

MDN : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

網址裡面也有範例,不過我還是摳一下網路上的用法

假設 JSON 如下

var myObj = {'test' : {'key1' : 'value', 'key2': 'value'}}

然後要刪掉 key1 就這樣下

delete myObj.test.key1;

就會變成

"{'test' : {'key2': 'value'}}"

 

四、刪除元素內指定元素值

這個可能就要靠手工

例如 JSON 如下 :

grobal = {

changeTimes: 0,

changeControl: [

{ "control" : "cname" },

{ "control" : "ename" },

{ "control" : "bokno" }

]

}

如果要刪除 { "control" : "ename" }

可以利用寫好的這個 function 

function removeJArray (arr,pid, val) {

for (var i = 0; i < arr.length; i++) {

var cur = arr[i];

if (cur[pid] == val) {

arr.splice(i, 1);

break;

}

}

}

只要這樣下就可以了

removeJArray (grobal.changeControl, "control", "ename");

 

五、 將 JSON 字串轉為 JSON 物件

JSON.parse

MSDN : http://msdn.microsoft.com/zh-tw/library/cc836466(v=vs.94).aspx

MDN : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

用法如下

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';

var contact = JSON.parse(jsontext);

document.write(contact.surname + ", " + contact.firstname);

 

或利用 jQuery 的 parseJSON

jQuery.parseJSON()

http://api.jquery.com/jquery.parsejson/

 

六、快速的尋找 JSON 中的值

可以用 JSON Select

http://jsonselect.org/#tryit

它可以讓你用簡單下 selector 的方式找到你要的值

到它網站上玩玩範例就會知道有多好用了

 

 

以下有想到或看到什麼好用的東西再補充

 

 

創作者介紹
創作者 小雕 的頭像
小雕

小雕雕的家

小雕 發表在 痞客邦 留言(0) 人氣()