行為型設(shè)計模式

特點;

可以順序的訪問聚合對象中的每個元素,

簡化循環(huán)語句,結(jié)構(gòu)清晰

迭代" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > web前端設(shè)計模式 (三)

web前端設(shè)計模式 (三)

時間:2023-09-04 08:42:02 | 來源:網(wǎng)站運營

時間:2023-09-04 08:42:02 來源:網(wǎng)站運營

web前端設(shè)計模式 (三):

一、設(shè)計模式

1.1 迭代器模式

定義:在不暴露對象內(nèi)部結(jié)構(gòu)的同時,可以順序的訪問聚合對象內(nèi)部的元素。

行為型設(shè)計模式

特點;

可以順序的訪問聚合對象中的每個元素,

簡化循環(huán)語句,結(jié)構(gòu)清晰

迭代器并沒有移出循環(huán)語句,而是移動到迭代器中。

迭代器在處理一個對象時,我們只需要提供處理方法,并不關(guān)系對象內(nèi)部結(jié)構(gòu)。

解決了使用者與對象內(nèi)部結(jié)構(gòu)解析之間的耦合

為我們提供統(tǒng)一的操作對象接口

<!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> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> </ul> <script> // ES6中提供了迭代器接口 // 我們實現(xiàn)一個類似jQuery的迭代器 function Iterator(selector) { // 存儲選擇器 this.selector = selector; // 獲取元素 this.elements = document.querySelectorAll(selector); // 維護(hù)一個索引自豪 this.index = 0; } // 提供一些方法 Iterator.prototype = { // 重寫構(gòu)造函數(shù) constructor: Iterator, // 獲取當(dāng)前元素 getCurrent: function() { return this.elements[this.index] }, // 獲取第一個 first: function() { // 更改index指向 this.index = 0; // 返回元素 return this.getCurrent(); }, // 前一個 prev: function() { this.index--; // 判斷邊界 if (this.index < 0) { this.index = 0; throw new Error('已經(jīng)是第一個了') } return this.getCurrent(); }, // 后一個 next: function() { this.index++; // 判斷邊界 if (this.index >= this.elements.length) { this.index = this.elements.length - 1; throw new Error('已經(jīng)是最后一個了'); } return this.getCurrent(); }, // 獲取最后一個 last: function() { // 更改index指向 this.index = this.elements.length - 1;; // 返回元素 return this.getCurrent();; }, // 獲取第幾個 eq: function(index) { this.index = index; return this.getCurrent(); } } // 獲取li var lis = new Iterator('li'); console.log(lis.first()) console.log(lis.last()) console.log(lis.prev()) console.log(lis.prev()) console.log(lis.next()) console.log(lis.eq(3)) </script></body></html>


1.2 委托模式

多個對象接收并處理同一請求,他們將請求委托給另一個對象統(tǒng)一處理請求。

解決請求與委托者之間的耦合

被委托者接收到請求分發(fā)給委托者去處理

應(yīng)用:

請求委托:

瀏覽器同時并發(fā)處理請求的個數(shù)是有限的,因此對于一個頁面來說,如果請求過多的話,會導(dǎo)致后面的請求被延遲(堵塞),我們?yōu)榱思涌爝@些請求發(fā)出,

我們將這些請求合并成一個,這樣當(dāng)請求結(jié)束后,我們在分發(fā)這些請求的數(shù)據(jù)

事件委托

1.3 事件委托

對于每一個元素我們都要綁定一個事件,這樣對于資源開銷很大(如果有1w個元素,要綁定1w個事件)

對于每一個類元素都要for循環(huán)遍歷一次,開發(fā)成本很高。所以我們可以通過事件委托來解決上面的問題

事件委托:將所有元素的事件綁定委托給同一個父元素,根據(jù)事件冒泡捕獲機(jī)制,可以在父元素綁定事件中獲取的觸發(fā)事件的這個元素,根據(jù)這個元素具有的某類

特征(例如元素名稱,元素id,元素類,元素屬性等等)做不同的處理,實現(xiàn)事件從父元素到被委托的元素傳遞。其特點:

減少事件數(shù)量

預(yù)言未來元素

新增的元素也可以綁定事件

避免內(nèi)存外泄:

通常創(chuàng)建一個對象需要占用一些內(nèi)存,這類占用是有意義的;有時候一些垃圾(已經(jīng)被刪除數(shù)據(jù))還占用著內(nèi)存,這部分內(nèi)存對我們來說是沒用的,就是

外泄內(nèi)存

jQuery中的事件委托

delegate:

第一個參數(shù)是被委托的元素(子元素)

第二個參數(shù)是事件類型

(這里還可以傳遞自定數(shù)據(jù))

第三個參數(shù)是事件回調(diào)函數(shù)

本質(zhì)上是調(diào)用的on方法,只不過他的委托語義化更強(qiáng)

<!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> <div id="box"> <button id="btn">按鈕</button> </div> <script> // 在低版本IE瀏覽器下會產(chǎn)生內(nèi)存外協(xié)的問題 // 高版本瀏覽器垃圾回收機(jī)制是計數(shù)的 // 低版本IE瀏覽器垃圾回收機(jī)制是引用的(指向的) // js中指向了元素,元素指向了js,此時將元素刪除,由于還與js有關(guān)系,因此不能被垃圾回收機(jī)制回收?? // 點擊按鈕,box顯示 "新內(nèi)容" // var btn = document.getElementById('btn'); // var box = document.getElementById('box'); // // 綁定事件 // btn.onclick = function() { // // 內(nèi)存外協(xié):box設(shè)置設(shè)置了新的內(nèi)容,按鈕元素被刪除了,但是按鈕元素還綁定了js中的click事件,因此沒辦法被銷毀,泄露在內(nèi)存中。 // // 更新box的內(nèi)容 // box.innerHTML = '新內(nèi)容' // }? // 使用事件委托模式,避免內(nèi)存外協(xié) var box = document.getElementById('box'); // 給盒子綁定事件 box.onclick = function(e) { // 判斷點擊的是否是按鈕 if (e.target.tagName.toUpperCase() === 'BUTTON') { // 更新盒子內(nèi)容 box.innerHTML = "新內(nèi)容"; } } </script></body></html>


1.4 節(jié)流器

定義:對重復(fù)的業(yè)務(wù)邏輯進(jìn)行節(jié)流控制,執(zhí)行最后一次操作并取消其它操作,以提高性能。

特點

延遲:通過計時器延遲程序的執(zhí)行

異步:通過計時器,使程序異步執(zhí)行,避免開銷大的程序造成的堵塞

條件

程序可控:即是否可以繼續(xù)執(zhí)行

異步執(zhí)行:即程序是否可以異步執(zhí)行

1.5 節(jié)流與防抖

節(jié)流器:觸發(fā)操作

讓程序延遲執(zhí)行

清除操作

清除還沒有執(zhí)行的操作

節(jié)流可以分成兩種

按操作節(jié)流

在規(guī)定時間內(nèi),重復(fù)執(zhí)行的時候,取消前一次執(zhí)行,執(zhí)行當(dāng)前的操作。

這種節(jié)流操作有的人也叫防抖,

例如:對返回頂部的優(yōu)化

按時間節(jié)流

在規(guī)定時間內(nèi),只允許執(zhí)行一次。

例如:對icon浮層的優(yōu)化

<!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> #back { position: fixed; right: 100px; bottom: 50px; width: 40px; height: 40px; padding: 15px; background-color: pink; font-size: 20px; color: green; } #qq { border: 1px solid pink; } #qq img { display: none; } </style></head><body> <div id="qq"> <span>官方QQ號</span> <img src="./qq.jpg" alt=""> </div> <h1>1-1-1</h1> <h1>2-2-2</h1> <h1>3-3-3</h1> <h1>4-4-4</h1> <h1>5-5-5</h1> <h1>6-6-6</h1> <h1>7-7-7</h1> <h1>8-8-8</h1> <h1>9-9-9</h1> <h1>10-10-10</h1> <h1>11-11-11</h1> <h1>12-12-12</h1> <h1>13-13-13</h1> <h1>14-14-14</h1> <h1>15-15-15</h1> <h1>16-16-16</h1> <h1>17-17-17</h1> <h1>18-18-18</h1> <h1>19-19-19</h1> <h1>20-20-20</h1> <div id="back">返回頂部</div> <script src="jquery.js"></script> <script> // 加載數(shù)據(jù)的方法 function getData() { // 當(dāng)滾動條距離頁面頂部的距離 + 視口的高度 + 300 > 頁面的高度 的時候,加載數(shù)據(jù) if (scrollY + innerHeight + 300 > document.body.clientHeight) { // 獲取數(shù)據(jù) $.get('data/all.json', function(res) { console.log(res); }) } } // 監(jiān)聽頁面滾動 window.onscroll = function() { // 返回頂部 // getData(); throttle(getData); }? // 基于時間,節(jié)流器方法 function throttle(fn, time, context, args) { // 在函數(shù)自身添加鎖 if (fn.__lock) { // 被鎖住了就不能執(zhí)行 return; } // 添加鎖 fn.__lock = true; // 執(zhí)行函數(shù) fn.apply(context, args); // 1秒之后解鎖 setTimeout(function() { fn.__lock = false; }, time || 1000) }? </script></body></html>


1.6 實現(xiàn) jQuery

jQuery本身是一個工廠方法

jQuery中,內(nèi)置了一個寄生類,寄生在原型上。

jQuery中,始終返回this即可實現(xiàn)鏈?zhǔn)秸{(diào)用

jQuery中,通過extend可以為jQuery添加靜態(tài)方法以及原型方法

<!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> <div class="app">hello</div> <div class="app">hello</div> <div class="app">hello</div> <script src="jquery.js"></script> <script> // $('.app').css('color', 'red').css({ // fontSize: '50px', // backgroundColor: 'pink' // }).attr('title', 'hello') </script> <!-- 實現(xiàn)jQuery --> <script> // // jQuery本身是一個工廠方法 // function jQuery(selector) { // // 返回實例 // return new init(selector) // } // // 真正的jQuery類 // function init() {? // }?? // jQuery本身是一個工廠方法 // function jQuery(selector) { // // 返回實例 // return new init(selector) // } // // 工廠方法的原型 // jQuery.prototype = { // // 更正構(gòu)造函數(shù) // constructor: jQuery, // // 將真正的jQ類放在了工廠方法的原型對象上 // // 每次訪問init都要寫 jQuery.prototype.init 太麻煩了,取了一個別名: jQuery.fn 代表原型對象 // init: init // } // // 真正的jQuery類 // function init() {? // }????? // jQuery本身是一個工廠方法 function jQuery(selector) { // 返回實例 // return new init(selector) // 重新訪問init return new jQuery.fn.init(selector); } // 工廠方法的原型 // 這樣訪問jQuery.fn 相當(dāng)于訪問jQuery.prototype jQuery.fn = jQuery.prototype = { // 更正構(gòu)造函數(shù) constructor: jQuery, // 將真正的jQ類放在了工廠方法的原型對象上 // 每次訪問init都要寫 jQuery.prototype.init 太麻煩了,取了一個別名: jQuery.fn 代表原型對象 // init: init, version: '1.0', demo() { console.log('demo') }, // 拓展一些方法,讓其更像數(shù)組 push: Array.prototype.push, splice: Array.prototype.splice } // 真正的jQuery類 jQuery.fn.init = function(selector) { // 根據(jù)選擇器,將元素獲取 var dom = document.querySelectorAll(selector); // 存儲選擇器 this.selector = selector; // 定義長度 this.length = 0; // 將獲取的元素,存儲再自身 for (var i = 0; i < dom.length; i++) { // 存儲一個成員并更改長度 this[i] = dom[i]; this.length ++; } } // 讓init類的實例,具有jQuery原型上的方法 // jQuery.fn.init.prototype = jQuery.prototype; jQuery.fn.init.prototype = jQuery.fn;? // jquery又定義了拓展方法 jQuery.extend = jQuery.fn.extend = function(obj) { // 解析對象 for (var key in obj) { this[key] = obj[key]; } } // 靜態(tài)屬性 // jQuery.extend({ // color: 'red' // }) // 拓展原型屬性 jQuery.fn.extend({ css: function(key, value) { // 如果key是字符串,直接賦值 if (typeof key === 'string') { // 給每一個元素設(shè)置樣式 for (var i = 0; i < this.length; i++) { this[i].style[key] = value; } } else { // 遍歷對象設(shè)置樣式 for (var k in key) { this.css(k, key[k]) } } // 鏈?zhǔn)秸{(diào)用 return this; }, // 設(shè)置屬性方法 attr: function(key, value) { // 為每一個成員設(shè)置屬性 for (var i = 0; i < this.length; i++) { this[i][key] = value; } } }) // 對jQuery起別名 var $ = jQuery; // console.log(jQuery('.app')); $('.app').css('color', 'red').css({ fontSize: '50px', backgroundColor: 'pink' }).attr('title', 'hello') console.log($('.app')); </script></body></html>

關(guān)鍵詞:模式,設(shè)計

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉