廣播: 關注微信公眾號“jQuery每日經典”,有更多資料。微信小程序 -- 前端技術API手冊 也在公眾號首次發布。有需要的聯系公眾號中QQ。
這一章話題的由來,還要從一些學員的作業說起。寫這篇文章主要是想讓大家能從不同的角度分析問題,學習的過程中多看,多練,多想,多查,多用心。在特別多的學習網站中大部分的學習資料基本都是循規蹈矩的,例如慕課網的 javascript 入門教程中,很多講師都講了一些實例,而這些例子中的代碼風格如出一轍,沒什么新意,而且這些教程占了很大一部分比例。在這里,給大家提供另外一種思路 ------ 監聽,具體代碼的實現大家自己實現。也歡迎大家評論區寫出不同想法。
先給出監聽的概念:監聽一個對象的某個屬性是否發生變化,在該屬性變化時立即觸發制定的回調函數。
實例:購物車,想必大家肯定都接觸過,那它的功能如何去實現呢?
以某寶購物車截圖為例:
一、功能概述
-
選中商品 -- 總數,總價發生變化
-
增加單類商品數量 -- 總數, 總價,單類商品總價 發生變化
-
刪除 單類商品 -- 總數總價發生變化
二、數據模型
單個商品數據模型{ischeck:是否選中, single:12, count, 2, total:24}
總商品數據模型{items:商品列表, totalCount:總數, totalPrice:總價}
三、常用邏輯
1. 點擊復選框(選中單類商品),修改總數 和 總價
代碼格式如下:
var
singleItem = document.getElementById("復選框");
singleItem.點擊事件 = function(){}
if(this選中){
總數=總數+this.count; 總價=總價+this.total; } else {
總數=總數-this.count; 總價=總價-this.total; }
}
|
四、監聽模式
監聽模式的另一個表達方式是觀察者模式,其實並沒有什么高級的。購物車這個功能用監聽模式可以描述為:當修改什么的時候,什么發生變化。
watch(item, 'isCheck', function(newVal, oldVal, obj){ if(newVal){ all['totalCount'] = all['totalCount'] + obj['count']; all['totalPrice'] = all['totalPrice'] + obj['total']; } else { ... } }); item['isCheck'] = false;
功能其實是一樣的,只不過是從“當修改什么的時候,去修改另外的什么”這種思想轉變為了“當修改什么的時候,什么發生變化”。
五、相關資料
1. Object.prototype.watch()
網址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/watch
例1:
var o = {p:1};
o.watch("p",function (id,oldval,newval) {
console.log("o."+id+"由"+oldval+" 變為 "+newval);
return newval;
});
o.p = 2;
o.p = 3;
上面的代碼顯示結果如下:
o.p 由 1 變為 2
o.p 由 2 變為 3
警告:這個方法是非標准的,僅在Gecko中實現了,並且這方法主要是為了在調試的時候使用。
2. github上也有一些watch.js的項目,
推薦一個:https://github.com/melanke/Watch.JS
具體使用情況和對它的評價網上有不少,大家可以看一下。
3. 自己實現
上面代碼中的watch方法其實是我自己手寫的,粗陋代碼如下:
function watch(obj, prop, callback){
if(prop in obj){
var old = obj[prop];
Object.defineProperty(obj,prop, {
enumerable: true,
configurable: true,
set: function(val) {
var o=old;old=val;
callback(val,o,obj);
},
get:function(){
return old;
}
});
} else {
throw new Error("no such property: " + pro);
}
}