摘要:觀察者模式介紹觀察者設(shè)計(jì)模式定義了對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,以便一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),所有依賴(lài)于它的對(duì)象都得到通知并自動(dòng)刷新。
觀察者模式介紹
觀察者設(shè)計(jì)模式定義了對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,以便一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí), 所有依賴(lài)于它的對(duì)象都得到通知并自動(dòng)刷新。
一些好的文章
觀察者模式與委托模式的區(qū)別
深入理解JavaScript系列(32):設(shè)計(jì)模式之觀察者模式
【Javascript設(shè)計(jì)模式3】-觀察者模式
可以使用的配置
childList: *true =========================可以觀察子元素
attributes: *true ========================可以觀察屬性
characterData: *true ====================可以觀察數(shù)據(jù)
subtree: *true =========================可以觀察所有后代
attributeOldValue: *true ==================可以保存屬性舊值
characterDataOldValue: ==================*true 可以保存數(shù)據(jù)舊值
attributeFilter: ==========================設(shè)置指定觀察屬性元素集合
note: Mutation Observers 被限制可以觀察Dom序列化狀態(tài) 在觀察textarea內(nèi)內(nèi)容改變時(shí) 無(wú)法觸發(fā)
observe 一個(gè)被觀察者對(duì)象 一份配置
void observe( Node target, MutationObserverInit options );
disconnet 斷開(kāi)觀察者與目標(biāo)鏈接
void disconnect();
takeRecords 返回對(duì)象所有觀察記錄
Array takeRecords();MutationObserver使用
不同瀏覽器之間存在兼容性問(wèn)題
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
html
- Press enter and look at the console
獲取list dom
var list = document.querySelector("ol");
實(shí)例化MutationObserver
var Observer = new MutationObserver(function(mutations){ });
Mutation Observer 對(duì)象
監(jiān)測(cè)childList
Observer.observe(list, { childList: true });
不過(guò)值得注意的是 這里觀測(cè)的是list直接child 如果要觀測(cè)child的child 就需要開(kāi)啟subtree
比如要檢測(cè)這樣的行為
list.childNodes[0].appendChild(document.createElement("div"));
observer需要更改配置
Observer.observe(list, { childList: true, subtree: true });
(mutationObserver觀測(cè)childlist) jsbin地址
observe 常見(jiàn)配置 及其解釋
observer.observe(target, {childList:true,subtree:true}) //subtree屬性讓觀察行為進(jìn)行"遞歸",這時(shí),以target節(jié)點(diǎn)為根節(jié)點(diǎn)的整棵DOM樹(shù)發(fā)生的變化都可能會(huì)被觀察到 observer.observe(document, {childList:true,subtree:true}) //如果target為document或者document.documentElement,則當(dāng)前文檔中所有的節(jié)點(diǎn)添加與刪除操作都會(huì)被觀察到 observer.observe(document, {childList:true,attributes:true,characterData:true,subtree:true}) //當(dāng)前文檔中幾乎所有類(lèi)型的節(jié)點(diǎn)變化都會(huì)被觀察到(包括屬性節(jié)點(diǎn)的變化和文本節(jié)點(diǎn)的變化等)
observe 觀察characterData
Observer.observe(list, {childList:true}); //假設(shè)此時(shí)target的outHTML內(nèi)容為foo,則: list.childNodes[0].data = "bar"; //不會(huì)觸發(fā)回調(diào)函數(shù),因?yàn)閏hildList只觀察節(jié)點(diǎn)的新建與刪除, 而這里target節(jié)點(diǎn)的子節(jié)點(diǎn)仍然只有一個(gè),沒(méi)有多,沒(méi)有少 Observer.observe(list, { childList:true,characterData:true}); //加上characterData屬性,允許觀察文本節(jié)點(diǎn)的變化,行不行? list.childNodes[0].data = "sds"; //還是不會(huì)觸發(fā)回調(diào)函數(shù),因?yàn)榘l(fā)生變化的是target節(jié)點(diǎn)的子節(jié)點(diǎn),我們目前的目標(biāo)節(jié)點(diǎn)只有一個(gè),就是target. Observer.observe(list, { childList:true,characterData:true,subtree:true}); //加上subtree屬性,觀察所有后代節(jié)點(diǎn) list.childNodes[0].data = "cha";(mutationObserver觀測(cè)characterdata) jsbin地址
observe 觀察attribute
Observer.observe(list, {attributes:true}); //只觀察目標(biāo)節(jié)點(diǎn)的屬性節(jié)點(diǎn) list.setAttribute("foo","bar"); //不管foo屬性存在不存在,都會(huì)觸發(fā)回調(diào)函數(shù) list.setAttribute("foo","bar"); //即使前后兩次的屬性值一樣,還是會(huì)觸發(fā)回調(diào)函數(shù) list.removeAttribute("foo"); //移除foo屬性節(jié)點(diǎn),觸發(fā)回調(diào)函數(shù) list.removeAttribute("foo"); //不會(huì)觸發(fā)回調(diào)函數(shù),因?yàn)橐呀?jīng)沒(méi)有屬性節(jié)點(diǎn)可移除了 Observer.observe(list, {attributes:true,attributeFilter:["bar"]}); //指定要觀察的屬性名 list.setAttribute("foo","bar"); //不會(huì)觸發(fā)回調(diào)函數(shù),因?yàn)閍ttributeFilter數(shù)組不包含"foo" list.setAttribute("bar","foo");(mutationObserver觀測(cè)attribute) jsbin地址
我們開(kāi)始做一個(gè)編輯器
功能 向前 向后并且按鈕要能隨時(shí)改變
ol設(shè)置為contenteditable時(shí),當(dāng)每次敲擊回車(chē)時(shí),ol的children會(huì)增加一個(gè)li 并且我們構(gòu)造一個(gè)observer監(jiān)聽(tīng)它子元素的變化, 這樣我們便可以獲得每次改變后所有新的children
var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === "childList") { var list_values = [].slice.call(list.children) .map( function(node) { return node.innerHTML; }) .filter( function(s) { if (s === "
") { return false; } else { return true; } }); console.log(list_values); } }); }); observer.observe(list, { attributes: true, childList: true, characterData: true });(觀察ol子元素的變化) jsbin地址
編輯器對(duì)與每行變化也需要監(jiān)測(cè), 我們可以自己構(gòu)造一個(gè)entry保存每次數(shù)據(jù)
var observer = new MutationObserver(function (mutations) { // Whether you iterate over mutations.. mutations.forEach(function (mutation) { // or use all mutation records is entirely up to you var entry = { mutation: mutation, el: mutation.target, value: mutation.target.textContent, oldValue: mutation.oldValue }; console.log("Recording mutation:", entry); }); });(ol監(jiān)測(cè)每一行變化) jsbin地址
編輯器統(tǒng)計(jì)字?jǐn)?shù)
var observer = new MutationObserver(function(mutations){ mutations.forEach(function(mutation){ if(mutation.type == "characterData") { var newValue = mutation.target.textContent; textinputcount.innerHTML = "還可以輸入"+(1000 - newValue.length+"字"); } });編輯器統(tǒng)計(jì)字?jǐn)?shù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/85815.html
相關(guān)文章
簡(jiǎn)要總結(jié)microtask和macrotask
摘要:眾所周知和都屬于上述異步任務(wù)的一種那到底為什么和會(huì)有順序之分這就是我想分析總結(jié)的問(wèn)題所在了和的作用是為了讓瀏覽器能夠從內(nèi)部獲取的內(nèi)容并確保執(zhí)行棧能夠順序進(jìn)行。只要執(zhí)行棧沒(méi)有其他在執(zhí)行,在每個(gè)結(jié)束時(shí),隊(duì)列就會(huì)在回調(diào)后處理。 前言 我是在做前端面試題中看到了setTimeout和Promise的比較,然后第一次看到了microtask和macrotask的概念,在閱讀了一些文章之后發(fā)現(xiàn)沒(méi)有...
js監(jiān)聽(tīng)div元素的寬高變化
摘要:構(gòu)造函數(shù),參數(shù)為回調(diào)函數(shù)構(gòu)造函數(shù)為,它在監(jiān)聽(tīng)到中的改變并且一系列改變結(jié)束后觸發(fā)回調(diào)函數(shù)。是要監(jiān)聽(tīng)的元素,為監(jiān)聽(tīng)選項(xiàng)對(duì)象,可選的選項(xiàng)如下所以監(jiān)聽(tīng)元素寬高變化,就是監(jiān)聽(tīng)屬性變化這樣當(dāng)元素發(fā)生變化時(shí),就會(huì)觸發(fā)構(gòu)造函數(shù)中的函數(shù)。 一、js監(jiān)聽(tīng)window變化的方法 1、onsize只能監(jiān)聽(tīng)window對(duì)象的變化 (1)、 window對(duì)象原生、jQuery方法 //原生寫(xiě)法 window.on...
淺析 Vue 2.6 中的 nextTick 方法
摘要:核心的異步延遲函數(shù),用于異步延遲調(diào)用函數(shù)優(yōu)先使用原生原本支持更廣,但在的中,觸摸事件處理程序中觸發(fā)會(huì)產(chǎn)生嚴(yán)重錯(cuò)誤的,回調(diào)被推入隊(duì)列但是隊(duì)列可能不會(huì)如期執(zhí)行。 淺析 Vue 2.6 中的 nextTick 方法。 事件循環(huán) JS 的 事件循環(huán) 和 任務(wù)隊(duì)列 其實(shí)是理解 nextTick 概念的關(guān)鍵。這個(gè)網(wǎng)上其實(shí)有很多優(yōu)質(zhì)的文章做了詳細(xì)介紹,我就簡(jiǎn)單過(guò)過(guò)了。 以下內(nèi)容適用于瀏覽器端 JS,...
JavaScript Event Loop 機(jī)制詳解與 Vue.js 中實(shí)踐應(yīng)用
摘要:機(jī)制詳解與中實(shí)踐應(yīng)用歸納于筆者的現(xiàn)代開(kāi)發(fā)語(yǔ)法基礎(chǔ)與實(shí)踐技巧系列文章。事件循環(huán)機(jī)制詳解與實(shí)踐應(yīng)用是典型的單線程單并發(fā)語(yǔ)言,即表示在同一時(shí)間片內(nèi)其只能執(zhí)行單個(gè)任務(wù)或者部分代碼片。 JavaScript Event Loop 機(jī)制詳解與 Vue.js 中實(shí)踐應(yīng)用歸納于筆者的現(xiàn)代 JavaScript 開(kāi)發(fā):語(yǔ)法基礎(chǔ)與實(shí)踐技巧系列文章。本文依次介紹了函數(shù)調(diào)用棧、MacroTask 與 Micr...
Event Loop執(zhí)行順序
摘要:簡(jiǎn)要介紹談?wù)勗陉?duì)列中的執(zhí)行順序問(wèn)題的來(lái)源都不陌生,是指主線程從任務(wù)隊(duì)列中循環(huán)讀取任務(wù),比如例輸出在上述的例子中,我們明白首先執(zhí)行主線程中的同步任務(wù),當(dāng)主線程任務(wù)執(zhí)行完畢后,再?gòu)闹凶x取任務(wù),因此先輸出,再輸出。 簡(jiǎn)要介紹:談?wù)刾romise.resove,setTimeout,setImmediate,process.nextTick在EvenLoop隊(duì)列中的執(zhí)行順序 問(wèn)題的來(lái)源 eve...
發(fā)表評(píng)論
0條評(píng)論
閱讀 3151·2021-09-22 15:20
閱讀 2671·2019-08-30 15:54
閱讀 2038·2019-08-30 14:06
閱讀 3187·2019-08-30 13:05
閱讀 2552·2019-08-29 18:36
閱讀 630·2019-08-29 15:10
閱讀 583·2019-08-29 11:17
閱讀 890·2019-08-28 18:11