首頁 web前端 js教程 JS控制項的生命週期介紹_javascript技巧

JS控制項的生命週期介紹_javascript技巧

May 16, 2016 pm 05:49 PM
生命週期

JS控件的生命周期跟其他平台UI的生命周期类似,但是又有自己的特点,我们只有将控件的生命周期划分清晰,所有的控件编写、mixins的编写和plugin的编写才能遵循控件的生命周期做统一的管理。在这里我把JS的生命周期定义为4部分:

1.initializer: 初始化,做一些不牵扯DOM操作的初始化操作
2.createDom: 创建 DOM,在这个过程中我们创建控件需要的DOM结构
3.renderUI: 生成控件的内部元素,在这里调用子控件的渲染方法,开启子控件的生命周期
4.bindUI: 绑定事件,可以绑定子控件事件也可以绑定内部DOM的事件
5.synUI: DOM结构以及子控件生成完毕后,我们在配置项中传入的值或者默认的配置项要应用到DOM上,例如 width,height,focusable之类的属性
6.destructor: 析构函数,移除控件,清理控件上的事件,清理子控件,清理控件自己的DOM以及控件的一些对其他控件的引用。


1

初始化:

控制初始化過程中做以下事情:
1.呼叫繼承的父類的初始化函數,包括原型鏈上的父類別和mixins
2.處理設定項,合併預設設定項和使用者傳入的設定項
3.處理綁定到改物件的事件
4.初始化外掛程式(plugin)
初始化完成後,是否建立DOM看具體的策略,類似ext的實現,可以延遲建立DOM

建立DOM

建立DOM的過程如下:
1.呼叫繼承的父類別的建立DOM的函數,包括原型鏈上的父類別和mixins
2.建立控制項的DOM
3.呼叫控制項插件的創建DOM的函數

渲染子控制與內部DOM操作

執行過程如下:
1.呼叫父類別的渲染函數,包含原型鏈上的父類別和mixins
2.呼叫插件的渲染函數
我們可以在頂層的父類別來初始化子控制項。好處是,子類別不需要做子控制項初始化的操作此時:
1.如果子控制項還未初始化則執行初始化
2.繼續執行子控制項的建立DOM、渲染子控制項、綁定事件、同步配置項目函數執行
綁定事件
由於此時控制項的DOM和內部的子控制項已經渲染完畢,則可以在子控制項或DOM上綁定事件。綁定事件的過程:
1.呼叫父類別的綁定事件方法,包括原型鏈上的父類別和mixins
2.呼叫父類別的綁定事件方式
注意:在子控制項或內部DOM上綁定事件時,使用委託,不要直接在子控制項或DOM上綁定事件,一旦子控制項新增或刪除,內部DOM變化都會造成事件失效。

同步配置項

首先說明一下什麼叫做同步配置項,前面我們在初始化控制項時,已經對配置項做過一定的處理(至於如何處理,後面講JS控制項屬性的時候會講到),但是配置項並未作用到DOM上或是內部子控制項上。
為什麼在這時候處理同步,而不是在創建DOM和渲染子控制項時,有2個原因:
1.在創建DOM和渲染子控制項時,所有的DOM和子控制項並未完整產生此時同步需要進行大量判斷
2.我們需要把同步配置項目的工作提取成方法,修改配置項時,內部DOM和子控件跟著變化。

例如:設定項裡有{ width : 100 }
1.如果我們在渲染DOM時同步,則可能把「width=100px;」直接設定到DOM上,而到我們需要修改這個width時,我們還需要寫一個函數來設定這個值。
2.反之,我們把同步配置項集中處理,將一個個的同步配置項的過程抽取成一個個函數,那麼我們初始化width的過程和修改width的過程完全一樣,這樣概念和邏輯就統一起來。
同步設定項的過程仍如其他步驟一樣:
1.呼叫父類別的同步方法,包括原型鏈上的父類別和mixins
2.呼叫外掛程式(plugin)的同步方法
注意:我們應該可以配置一個配置項是否在此時同步,原因有很多,例如多個配置項會產生相同操作,如果多個配置項同時同步,那麼一個過程會重複執行多次。
移除控制
任何物件都有建構函數,必定也有析構函數,但是這個函數往往是大家最容易忽略的地方,但是也是非常重要的地方,暫且不說記憶體外洩之類的問題,就是如果一個控制項的移除工作做得不夠好,會對正常的使用帶來很大的麻煩。
這個函數又是最不好寫的一個函數,因為它需要處理以下工作:
1.清理使用的其他控件,是否也移除看具體情形。區分關聯和聚合
2.清理子控制
3.清理綁定到控制項和DOM上的事件
4.移除DOM
5.清理變數的引用,這個比較麻煩和繁瑣,所以我們需要對控制項的參考做統一的管理
同樣此函數也要執行:
1.呼叫父類的析構函數,包括原型鏈上的父類和mixins
2.調用插件的析構函數

問題

上面講的全部是具體的步驟,但是在實現的時候遇到了一系列的問題:
1.呼叫父類別的方法有問題
1)呼叫原型鏈上的父類別方法,只能使用className.superclass.method.call(this)這類的方法,this.constructor.superclass.method.call(this )不能使用,原因在js 控制項繼承的extend一章中有講到,這種呼叫方式繁瑣而且維護不方便。
2)呼叫mixins上的方法,在JS 繼承mixins一章中我講到過mixins的實作原理,覆寫同名方法,mixins的方法其實已經作為控制項的prototype上的方法,所以最好不要使用同名方法,如果多個mixins都是用renderUI,synUI之類的方法,而繼承這些mixins的控制項並沒有實作renderUI這類方法,那麼就會被覆寫。
2.呼叫外掛程式的方法也存在問題
1)我們需要取得目前控制項的參考

解決方式:

1.針對父呼叫類別的方法我們可以在控制項渲染時,按照原型鏈的順序,先呼叫父類別的方法再呼叫子類別的方法直到目前控制項:


如上面的繼承關係,我們執行C.renderUI()時,依照繼承原型鏈的頂層向下執行。
2. 執行minxins的方法,我們執行renderUI時,去依序執行 mixin 的__renderUI方法。
3. 執行父類別的renderUI 時,如果也存在mixins那麼執行mixin的 __renderUI方法。



圖3

如上圖: inherits表示原型鏈繼承,extends表示mixin擴充
那麼c.renderUI的執行過程如下:

A.renderUI ->D.__renderUI->B.renderUI- >E.__renderUI->C.renderUI
3. 呼叫插件方法時需要傳遞控製本身的引用即可,如:
plugin1.render(this)
4. 析構函數destructor比較特使,執行的順序跟上面2講的順序有所不同:
子類destructor -> 子類擴展destructor -> 父類destructor -> 父類擴展destructor
按照圖3的繼承結構其析構函數執行的順序是:
C. destructor ->E.__destructor->B.destructor->E.__destructor->a.destructor
原因是,子類的一些引用依賴於父類或擴展類,如果父類別和擴充類別先執行析構函數,那麼子類別在使用某些變數/屬性時會報錯。

這一節我把控制項的生命週期講了一遍,所有的著一些都是來自於KISSY框架的UIBase,感興趣的可以去看一下,非常精彩的實現 http://docs.kissyui.com/kissy/docs/#!/api/KISSY.Component.UIBase

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vue3改了幾個生命週期函數 vue3改了幾個生命週期函數 Jan 13, 2023 pm 05:57 PM

vue3改了4個生命週期函數。 Vue3組合式api取消了beforeCreated和created鉤子函數,採用steup鉤子代替,且裡面不能使用this。 Vue3裡面的組件銷毀的鉤子函數由destroyed和beforeDestroy換成了beforeUnmount和unmounted。

servlet生命週期分成幾個階段 servlet生命週期分成幾個階段 Feb 23, 2023 pm 01:46 PM

Servlet生命週期是指servlet從創建到毀滅的整個過程,可分為3個階段:1、初始化階段,呼叫init()方法實作Servlet的初始化工作;2、運行階段(處理請求),容器會為指定請求建立代表HTTP請求的ServletRequest對象和代表HTTP回應的ServletResponse對象,然後將它們作為參數傳遞給Servlet的service()方法;3、銷毀階段。

如何處理 C++ 函數指標的析構與生命週期管理? 如何處理 C++ 函數指標的析構與生命週期管理? Apr 17, 2024 pm 05:48 PM

在C++中,函數指標需要適當的析構和生命週期管理。可以透過以下方式實現:手動析構函數指針,釋放記憶體。使用智慧指針,如std::unique_ptr或std::shared_ptr,自動管理函數指標的生命週期。將函數指標綁定到對象,對像生命週期管理函數指標的析構。在GUI程式設計中,使用智慧指標或綁定到物件可確保回呼函數在適當的時候被析構,避免記憶體洩漏和不一致。

Vue3中的生命週期函數:快速掌握Vue3的生命週期 Vue3中的生命週期函數:快速掌握Vue3的生命週期 Jun 18, 2023 am 08:20 AM

Vue3是目前前端界最熱門的框架之一,而Vue3的生命週期函數是Vue3中非常重要的一部分。 Vue3的生命週期函數可以讓我們實現在特定的時機觸發特定的事件,增強了元件的高度可控性。本文將從Vue3的生命週期函數的基本概念、各個生命週期函數的作用和使用方法以及實現案例等方面進行詳細探究和講解,幫助讀者快速掌握Vue3的生命週期函數。一、Vue3的生命週期函數的

uniapp實作如何手動觸發元件的生命週期鉤子函數 uniapp實作如何手動觸發元件的生命週期鉤子函數 Oct 21, 2023 am 11:04 AM

Uniapp是一款跨平台的應用程式開發框架,可同時建構iOS、Android和Web應用。在應用開發過程中,組件的生命週期鉤子函數是非常重要的一部分,它們用於在特定的時間節點執行相應的操作。通常,元件的生命週期函數是在特定的事件觸發下自動執行的,例如頁面載入完成、元件進入視圖、元件從視圖中移除等。但是,有時我們需要手動觸發組件的生命週期鉤子函數,以便達到特定的

如何控制 Golang 協程的生命週期? 如何控制 Golang 協程的生命週期? May 31, 2024 pm 06:05 PM

控制Go協程的生命週期可以透過以下方式:建立協程:使用go關鍵字啟動新任務。終止協程:等待所有協程完成,使用sync.WaitGroup。使用通道關閉訊號。使用上下文context.Context。

vue3的生命週期有哪些 vue3的生命週期有哪些 Feb 01, 2024 pm 04:33 PM

vue3的生命週期:1、beforeCreate;2、created;3、beforeMount;4、mounted;5、beforeUpdate;6、updated;7、beforeDestroy;8、destroyed;9、activated;10、deactivated;11、errorCaptured;12 、getDerivedStateFromProps 等等

Go語言中的變數作用域與生命週期 Go語言中的變數作用域與生命週期 Jun 01, 2023 pm 12:31 PM

Go語言是一種開源的靜態型別語言,它具有簡潔、高效、可靠等特點,越來越受到開發者的喜愛。在Go語言中,變數是程式中最基本的資料儲存形式,變數的作用域和生命週期對於程式的正確性和效率十分重要。變數的作用域指的是變數的可見性和可訪問性,即在何處可以存取這個變數。在Go語言中,變數的作用域分為全域變數和局部變數。全域變數是定義在函數外部的變量,它可以被整個程式任何

See all articles