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