時(shí)間:2023-09-04 02:54:01 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-09-04 02:54:01 來源:網(wǎng)站運(yùn)營
web前端之設(shè)計(jì)模式(二):<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <script> // 觀察者模式又叫發(fā)布訂閱者模式,消息系統(tǒng),消息機(jī)制,自定義事件 var Observer = (function() { // 消息隊(duì)列 var _msg = {}; // 暴露接口 return { /*** * 訂閱消息 * @type 消息名稱 * fn 回調(diào)函數(shù) * 將消息回調(diào)函數(shù),存儲(chǔ)在消息隊(duì)列中 **/ on: function(type, fn) { // 判斷這種類型的消息是否存在 if (_msg[type]) { // 繼續(xù)存儲(chǔ) _msg[type].push(fn) } else { // 初始化一個(gè)消息管道 _msg[type] = [fn] } // console.log(_msg); }, /*** * 發(fā)布消息 * @type 消息類型 * 從第二個(gè)參數(shù)開始,表示執(zhí)行消息回調(diào)函數(shù)的時(shí)候,傳遞的參數(shù) * 遍歷該類型的消息回調(diào)函數(shù),并逐一執(zhí)行 **/ trigger: function(type) { // 該類型的消息是否存在 if (_msg[type]) { // 獲取傳遞的參數(shù) var args = Array.prototype.slice.call(arguments, 1); // console.log(args); // 遍歷消息管道,逐一執(zhí)行每一個(gè)方法 for(var i = 0; i < _msg[type].length; i++) { // 執(zhí)行每一個(gè)函數(shù), // args是一個(gè)數(shù)組,要逐一傳遞,因此要借助apply _msg[type][i].apply(null, args) // _msg[type][i](args) } } }, /*** * 注銷消息 * @type 消息名稱 * fn 回調(diào)函數(shù) 注意:匿名函數(shù)無法注銷 * 從消息隊(duì)列中,移除該回調(diào)函數(shù) **/ off: function(type, fn) { // 沒有傳遞參數(shù),情況消息隊(duì)列 // 傳遞了type,情況該類型的消息管道 // 傳遞了type和fn,從該類型的消息管道中,找到fn,并將其移除? // 沒有傳遞參數(shù),情況消息隊(duì)列 if (type === undefined) { _msg = {}; return; } // 是否有fn if (fn) { // 傳遞了type和fn,從該類型的消息管道中,找到fn,并將其移除 for (var i = _msg[type].length - 1; i >= 0; i--) { // 尋找fn if (_msg[type][i] === fn) { // 移除fn, 從后向前遍歷時(shí)候,從數(shù)組中刪除成員不會(huì)影響遍歷 _msg[type].splice(i, 1) // 刪除了,不需要繼續(xù)遍歷了。 return; } } } else { // 傳遞了type,情況該類型的消息管道 _msg[type] = []; } }, /*** * 單次訂閱的 * @type 消息名稱 * fn 回調(diào)函數(shù) * 注冊(cè)后將其移除 **/ once: function(type, fn) { // this.on(type, fn) // this.off(type, fn) // 緩存this var me = this; // 包裝函數(shù) function callback() { // 注銷回調(diào)函數(shù), 防止無限循環(huán)。 me.off(type, callback) // 執(zhí)行回調(diào)函數(shù),并傳遞參數(shù) // apply第二個(gè)參數(shù)可以是數(shù)組,也可以是類數(shù)組對(duì)象。 fn.apply(null, arguments); // console.log('執(zhí)行了') } // 訂閱 this.on(type, callback) } } })()?? // 觀察者模式問題:一定是先訂閱,再發(fā)布。 Observer.trigger('test', 100, 200)? // 單次訂閱 Observer.once('test', function() { console.log('run test', arguments); Observer.trigger('test', 'hello', 'ickt') })? // Observer.trigger('test', 100, 200) // Observer.trigger('test', true, false) // Observer.trigger('test', 'hello', 'ickt')?? // function demo() { // // console.log('helle ickt', this) // console.log('helle ickt') // } // // 訂閱消息 // Observer.on('ickt', function(num1, num2, bool, msg) { // // console.log(arguments) // console.log(num1, num2, bool, msg); // }) // Observer.on('ickt', demo) // Observer.on('demo', function() { // console.log(arguments) // }) // // 清空 // // Observer.off(); // // Observer.off('ickt'); // // 沒辦法注銷匿名函數(shù) // // Observer.off('ickt', function() { // // // console.log('helle ickt', this) // // console.log('helle ickt') // // }); // // Observer.off('ickt', demo)? // // 發(fā)布消息 // Observer.trigger('ickt', 100, 200, true, 'hello') // Observer.trigger('ickt', 100, 200, true, 'hello') // Observer.trigger('test', 100, 200) // Observer.trigger('demo', 100, 200)? </script></body></html>
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> a:hover { color: #f90; } a { margin-right: 20px; } </style></head><body> <script src="./ickt.js"></script> <script> // 定義基類,讓所有類繼承 function Base() { // 當(dāng)前元素 this.element = null; // 存儲(chǔ)子類 this.children = []; } // 定義這些行文方法 Base.prototype.init = function() { // 基類不能初始化 throw new Error('基類不能初始化') } // 獲取當(dāng)前實(shí)例對(duì)應(yīng)的元素 Base.prototype.getElement = function() { return this.element; } // 添加子元素 Base.prototype.add = function(child) { // 存儲(chǔ)子對(duì)象 this.children.push(child); // 處理dom this.element.appendChild(child.getElement()); // 鏈?zhǔn)秸{(diào)用 return this; } // 容器類 function Container(id, parent) { // 構(gòu)造函數(shù)式繼承 Base.call(this); // 存儲(chǔ)數(shù)據(jù) this.id = id; this.parent = parent; // 初始化 this.init(); } // 可以使用類式繼承,也可以使用寄生式繼承 // Container.prototype = new Base(); _.inherit(Container, Base); // 重寫方法 // 初始化方法 Container.prototype.init = function() { // 創(chuàng)建元素 this.element = document.createElement('ul'); // 添加id this.element.id = this.id; // 添加類 this.element.className = 'container' } // 顯示容器 Container.prototype.show = function() { // 讓容器元素上樹 this.parent.appendChild(this.element); }? // 每一行的類 function Item(className) { // 構(gòu)造函數(shù)繼承 Base.call(this); // 存儲(chǔ)數(shù)據(jù) this.className = className || 'item'; // 初始化 this.init(); } // 繼承 _.inherit(Item, Base); // 重寫方法 Item.prototype.init = function() { // 創(chuàng)建元素 this.element = document.createElement('li'); // 設(shè)置屬性 this.element.className = this.className; }? // 沒有分類的新聞 function TitleNews(text, href) { // 構(gòu)造函數(shù)繼承 Base.call(this); // 存儲(chǔ)數(shù)據(jù) this.text = text; this.href = href; // 初始化 this.init(); } // 繼承 _.inherit(TitleNews, Base) // 重寫方法 // 初始化方法 TitleNews.prototype.init = function() { // 定義元素 this.element = document.createElement('a'); // 設(shè)置屬性 this.element.href = this.href; // 設(shè)置內(nèi)容 this.element.innerHTML = this.text; }? // 分類新聞 function TypeNews(text, href, type) { // 構(gòu)造函數(shù)繼承 Base.call(this); // 存儲(chǔ)數(shù)據(jù) this.text = text; this.href = href; this.type = type; // 初始化 this.init(); } // 繼承 _.inherit(TypeNews, Base) // 重寫方法 // 初始化方法 TypeNews.prototype.init = function() { // 創(chuàng)建元素 this.element = document.createElement('a'); var span = document.createElement('span'); var text = document.createTextNode(this.text); // 設(shè)置內(nèi)容 span.innerHTML = this.type + ' | '; // 設(shè)置屬性 this.element.href = this.href; // 組裝 this.element.appendChild(span) this.element.appendChild(text) }??? // 使用類 new Container('sport', document.body) .add( new Item() .add( new TitleNews('國安官宣與池忠國完成續(xù)約', 'www.baidu.com') ) .add( new TitleNews('足協(xié)明確外援出場規(guī)則', 'www.baidu.com') ) ) .add( new Item() .add( new TitleNews('180萬!詹皇球星卡拍賣創(chuàng)紀(jì)錄', 'www.baidu.com') ) ) .add( new Item() .add( new TypeNews('沈夢(mèng)辰時(shí)髦穿搭 趙麗穎夏日針織', '#demo', '時(shí)尚') ) ) .add( new Item() .add( new TypeNews('影院歸來票房超350萬:賠本攢人氣 但總要開始', '#demo', '科技') ) ) // 上樹 .show();? // 構(gòu)造一個(gè)新模塊 new Container('car', document.body) .add( new Item() .add( new TitleNews('小鵬汽車完成C+輪近5億美元融資', '#demo') ) ) .add( new Item() .add( new TypeNews('理想汽車計(jì)劃7月31日在納斯達(dá)克掛牌上市', '#demo', '汽車') ) ) .show(); </script></body></html>
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <input type="text"> <script> // 封裝校驗(yàn)算法 var strage = (function() { // 校驗(yàn)算法 var methods = { // 校驗(yàn)數(shù)字 number: function(value) { // 判斷數(shù)組 if (!/^/d+$/.test(value)) { // 不是數(shù)字 return '不是數(shù)字' } }, // 校驗(yàn)內(nèi)容 en: function(value) { // 判斷數(shù)組 if (!/^[a-zA-Z]+$/.test(value)) { // 不是數(shù)字 return '不都是英文' } } } // 接口方法 return { // 校驗(yàn)方法 use: function(type, value) { // 找到校驗(yàn)策略,校驗(yàn)數(shù)據(jù) return methods[type] && methods[type](value) }, // 添加策略 add: function(type, fn) { // 存儲(chǔ)校驗(yàn)策略 methods[type] = fn; } } })()? // 輸入框輸入完成 var inp = document.getElementsByTagName('input')[0]; // 失去焦點(diǎn) inp.onblur = function(e) { // 校驗(yàn) // var result = strage.use('number', e.target.value) // var result = strage.use('en', e.target.value) // 添加校驗(yàn)方法 strage.add('nickname', function(value) { // 校驗(yàn) if (!/^/w{2,8}$/.test(value)) { // 提示錯(cuò)誤 return '用戶名是2到8為的字母數(shù)字下劃線'; } }) var result = strage.use('nickname', e.target.value) console.log(result); } </script></body></html>
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body style="text-align: center;"> <canvas width="1000" height="600" style="border: 1px solid pink"></canvas> <script> // // 獲取canvas // var canvas = document.getElementsByTagName('canvas')[0]; // // 設(shè)置樣式 // canvas.style.border = '1px solid pink'; // // 繪制圓 // var ctx = canvas.getContext('2d'); // // 繪制元素 // ctx.beginPath(); // // 繪制圓 // ctx.arc(200, 200, 100, 0, Math.PI * 2); // ctx.closePath(); // // 設(shè)置顏色 // ctx.strokeStyle = 'green'; // ctx.stroke();? // 分裝一個(gè)指令對(duì)象 var Command = (function() { // 獲取canvas var canvas = document.getElementsByTagName('canvas')[0]; // 繪制圓 var ctx = canvas.getContext('2d'); // 封裝指令 var _C = { // 描邊圓 strokeCircle: function(x, y, r, color) { ctx.beginPath(); ctx.arc(x, y, r, 0, 2 * Math.PI); ctx.closePath(); // 設(shè)置顏色并描邊 ctx.strokeStyle = color; ctx.stroke(); }, // 填充元素 fillCircle: function(x, y, r, color) { ctx.beginPath(); ctx.arc(x, y, r, 0, 2 * Math.PI); ctx.closePath(); // 設(shè)置顏色并描邊 ctx.fillStyle = color; ctx.fill(); }, // 繪制矩形 fillCenterRect: function(x, y, width, height, color) { // 傳遞了顏色,設(shè)置顏色 if (color) { ctx.fillStyle = color; } // 繪制 ctx.fillRect(x - width / 2, y - height / 2, width, height) } } // 暴露接口 return { // 執(zhí)行方法 exec: function(type) { // 獲取第二個(gè)參數(shù)開始,傳遞的參數(shù) var args = Array.prototype.slice.call(arguments, 1); // 執(zhí)行指令 _C[type] && _C[type].apply(null, args); // 鏈?zhǔn)秸{(diào)用 return this; } } })()? // 繪制圓 Command.exec('fillCircle', 100, 100, 50, 'green') Command.exec('strokeCircle', 300, 300, 50, 'pink') // 還可以鏈?zhǔn)秸{(diào)用 .exec('fillCircle', 300, 100, 50, 'green') .exec('fillCenterRect', 400, 200, 100, 100, 'orange') </script></body></html>
關(guān)鍵詞:模式,設(shè)計(jì)
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。