javascript --- [虛擬DOM] 初始化 實現

說明

  • 本篇主要說明為什么要使用虛擬DOM技術,以及如何實現簡單的虛擬dom
  • 您將會學到:
    1.原生JS對DOM的操作
    2.虛擬DOM的相關概念
    3.DIFF算法的基礎概念

為什么提出 -> DOM操作慢

  • 我們使用createElement屬性來創建一個最常見的div,看看一個最常見的DOM有多少個屬性
<script>const div = document.createElement('div');let str = '';for(let key in div){str += key + ' ';}console.log(str);
</script>

在這里插入圖片描述

  • 可以看出,每個DOM其實是由很多內置的屬性.因此,當DOM元素的操作過多的時候,其性能可想而知.
  • 這就迫使我們去想一個辦法去減少DOM操作

為什么提出 -> 對比Ajax技術的出現

  • 早期的網頁交互,是整個頁面進行更新的.
  • 但是大多數時候,用戶對頁面的操作,只是一小部分,這就導致了大多數更新是多余的.
  • 于是產生了Ajax技術(網頁的部分更新)
  • 可以模仿Ajax技術,去部分渲染DOM

為什么提出 -> DOM樹的概念

  • 你可以會反駁,減少DOM的操作,不一定非要用到虛擬DOM,而可以直接對DOM進行操作.
  • 這就得先理解DOM樹.
  • 先看一個瀏覽器得請求過程:
    1.用戶輸入網址后,瀏覽器像服務器發送HTTP請求獲得HTML頁面
    2.得到頁面后,HTML解釋器、詞法分析器、語法分析器就會把HTML從字節流解釋成DOM樹的結構(過程比較復雜,也許會開一篇新文章具體說明)
    3.得到DOM樹后,WebKit會分批次的將結果詞語返回給渲染線程進行渲染
  • 上面對DOM的產生和渲染說的比較細了,這樣說的主要原因是: 說明沒有一個類或者方法,可以得到內存中待渲染的DOM樹(有可能要,但是我不知道QAQ).
  • 下面開始逐步實現虛擬DOM

createElement

  • 我們想實現以下結構
    在這里插入圖片描述
  • 語法如下:
let vertualDom = createElement('ul', { class: 'list'}, [createElement('ul', { class: 'list'}, ['a']),createElement('ul', { class: 'list'}, ['b']),createElement('ul', { class: 'list'}, ['c'])
])
  • 我們想通過createElement之后,變為對象,結構如下:
    在這里插入圖片描述
  • 很顯然,可以在創建虛擬節點時,返回一個VNode類,其中包含3個屬性(type、props、children)
class VNode {constructor(type, props, children) {this.type = type;this.props = props;this.children = children;}
}const createElement = (type, props, children) {return new VNode(type, props, children);
}
  • 上面之后,就可以返回一個虛擬DOM對象了.
  • 下面需要一個render方法,根據 虛擬DOM對象 來生成真實的DOM,并渲染.

render

  • render方法接收一個虛擬dom對象,根據對象創建真實的DOM
  • 1.首先我們根據傳入的對象,創建ul
const render = (vnode) {let el = document.createElement(vnode.type);return el;
}
  • 打印一下:
let vertualDom = createElement('ul', { class: 'list' }, [createElement('ul', { class: 'list' }, ['a']),createElement('ul', { class: 'list' }, ['b']),createElement('ul', { class: 'list' }, ['c']),
])let el = render(vertualDom);console.log(el);

在這里插入圖片描述

  • 2.有了DOM之后,我們給dom設置屬性.由于屬性可能比較多,
  • 因此我們使用for ... in 拿到鍵和值
  • 使用setAttribute來設置屬性
const render = (vnode)  => {let el = document.createElement(vnode.type);let props = vnode.type;for(let key in props) {el.setAttribute(key, props[key]);}
}

在這里插入圖片描述

  • 檢測一下,改寫vertualDom
let vertualDom = createElement('ul', { class: 'list', style:'border:1px solid black' }, [createElement('ul', { class: 'list' }, ['a']),createElement('ul', { class: 'list' }, ['b']),createElement('ul', { class: 'list' }, ['c']),
])
let el = render(vertualDom);
document.body.appendChild(el);

在這里插入圖片描述

  • 現在有了節點和節點上面的屬性,下面需要渲染其子元素…
  • 很自然的想到了遞歸.
  • 遍歷其子元素,如果是VNode類型,就在調用render,否則認為其是一個文本節點.使用document.createTextNode創之
const render = (vnode) => {let el = document.createElement(vnode.type);let props = vnode.props;for (let key in props) {el.setAttribute(key, props[key]);}vnode.children.forEach(child => {child = child instanceof VNode ? render(child) : document.createTextNode(child);el.appendChild(child);})return el;
}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250409.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250409.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

模塊單元學習筆記(日志記錄模塊os模塊sys)

一、日志記錄模塊 Logging 默認情況下&#xff0c;logging將日志打印到屏幕&#xff0c;日志級別大小關系為&#xff1a;CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET&#xff0c;當然也可以自己定義日志級別。 DEBUG&#xff1a;詳細的信息,通常只出現…

webpack --- [4.x]你能看懂的webpack項目初始化

說明: 本篇文章主要做如下事情: 創建一個基本的webpack4.x 項目[報錯]: The mode option has not been set, webpack will fallback to production for this value[報錯]: ERROR in Entry module not found: Error: Can not resolve ./src in D:\L-react\HeiMa\01.webpack-ba…

tomcat8 進入不了Manager App 界面 403 Access Denied

準備 1.注釋掉context.xml中的value屬性 使用下面的命令&#xff1a; vim /usr/local/tomcats/tomcat-daily/webapps/manager/META-INF/context.xml 注釋掉其中value節點 2.修改tomcat-users.xml文件 加入下面的配置 <role rolename"manager-gui" /><role …

SCRIPT70: 沒有權限

主要原因&#xff1a;iframe安全而引發的問題&#xff0c;瀏覽器中js是沒有垮域訪問的權限的。如果用到iframe首先確保不垮域&#xff0c;或者不用iframe以繞開這個問題。 另外在jquery的早期版本中如&#xff1a;jquery-1.9.1.js $(#iframeWeb).attr(src, url);出現這樣的問題…

webpack --- 在項目中使用React

說明: 分為2步: 首先導入react 和 react-dom:保證了虛擬DOM的創建和使用使用babel轉碼器: 由于DOM結構太多,每次使用React.createElement創建虛擬DOM會給開發帶來很大壓力,因此采用html的寫法,通過babel轉碼器轉換成React語法,可以很大程度上提高開發效率 項目源代碼 在項目…

js改變select下拉框默認選擇的option

比較簡單&#xff0c;記錄一下 var obj document.getElementById("fun"); obj.options[0].selected true; 轉載于:https://www.cnblogs.com/vicF/p/9844028.html

vue攔截器實現統一token,并兼容IE9驗證

項目中使用vue搭建前端頁面&#xff0c;并通過axios請求后臺api接口&#xff0c;完成數據交互。如果驗證口令token寫在在每次的接口中&#xff0c;也是個不小的體力活&#xff0c;而且也不靈活。這里分享使用vue自帶攔截器&#xff0c;給每次請求的頭部添加token&#xff0c;而…

Android Studio --- [學習筆記]Button、TextView、EditText

說明 源代碼為了更全面的了解RN,先熟悉一下Android開發 第1章 Android 初體驗 1.1 Android開發概述 Android是Google開發的操作系統Android開發是移動應用開發的表現形式之一(Android、IOS、H5 App、Native H5、 RN、ionic、MUI…) 1.2 Android開發工具 Android Studio為…

BZOJ2154: Crash的數字表格 BZOJ2693: jzptab

【傳送門&#xff1a;BZOJ2154&BZOJ2693】 簡要題意&#xff1a; 給出n,m&#xff0c;求$\sum_{i1}^{n}\sum_{j1}^{m}LCM(i,j)$ 題解&#xff1a; 莫比烏斯反演&#xff08;因為BZOJ2693是多組數據&#xff0c;數據強一點&#xff0c;所以代碼用BZOJ2693的&#xff09; 設n…

對于數據庫表排他更新的理解

1. 首先任何應用程序都只能有一個服務端&#xff0c;服務端共享數據給多個客戶端訪問。 (ア) 客戶端從服務端取得相應的數據。 (イ) 或者更新、刪除服務端的內容。 2. 當客戶端A進入服務端方法更新數據庫&#xff0c;服務端方法將被鎖定。其它客戶端在訪問該方法時&#xff0c…

Angular 路由守衛

1. 路由 Angular路由: 可以控制頁面跳轉&#xff1b;可以在多視圖間切換&#xff1b; 2. 路由守衛 Angular路由守衛&#xff1a; 在進入或離開某路由時&#xff0c;用于判斷是否可以離開、進入某路由&#xff1b;&#xff1b;&#xff1b; return true 代表可以進入當前路由&am…

Vue頁面手動刷新,導航欄激活項還原到初始狀態問題解決方案

場景描述&#xff1a;在頁面中存在頂部導航和左側導航&#xff0c;左側導航和右側內容區使用了命名視圖實現&#xff0c;點擊左側導航的鏈接時&#xff0c;右側內容區相應顯示不同組件內容。問題&#xff1a;在當前鏈接手動刷新瀏覽器&#xff08;例如&#xff1a;瀏覽器地址為…

Android Studio --- [學習筆記]RadioButton、CheckBox、ImageView、ListView、TCP的三次握手

說明 源代碼在2.x里有TCP的三次揮手與四次握手,先對它進行簡單的回答(百度).預計在下一篇里,會繼續說明TCP接上一篇: Android Studio — > [學習筆記]Button、TextView、EditText 2.5 RadioButton 常用屬性自定義樣式監聽事件 2.5.1 新建按鈕,并跳轉到相應的活動頁面 1.…

洛谷3171 網絡吞吐量(網絡流)

t開成n結果cur賦值的時候也只賦值到t令人智熄 【題目分析】 好吧我承認這個錯誤真的呵呵。。。。。。。。 題目有那~~~~~么長&#xff0c;然后畫畫圖這道題就基本看出正解了&#xff0c;再一看數據范圍&#xff0c;n<500簡直良心&#xff0c;好了&#xff0c;網絡流沒得跑了…

DIV+CSS布局的優勢和弊端

DIVCSS的優勢1、符合W3C標準。這保證您的網站不會因為將來網絡應用的升級而被淘汰。2、對瀏覽者和瀏覽器更具親和力。由于CSS富含豐富的樣式&#xff0c;使頁面更加靈活性&#xff0c;它可以根據不同的瀏覽器&#xff0c;而達到顯示效果的統一和不變形。這樣就支持瀏覽器的向后…

Android Studio --- [學習筆記]TCP(第2彈)、GridView、ScrollView

說明 這篇主要接上一篇Android Studio — > [學習筆記]RadioButton、CheckBox、ImageView、ListView、TCP的三次握手對上面回答的細解,并用JS偽代碼,對TCP三次握手和四次揮手的簡單實現.Android的基本了解到此篇結束,后續會根據具體情況深度學習. 2.y TCP的三次握手和四次揮…

MySQL中varchar最大長度是多少

一. varchar存儲規則&#xff1a; 4.0版本以下&#xff0c;varchar(20)&#xff0c;指的是20字節&#xff0c;如果存放UTF8漢字時&#xff0c;只能存6個&#xff08;每個漢字3字節&#xff09; 5.0版本以上&#xff0c;varchar(20)&#xff0c;指的是20字符&#xff0c;無論存放…

bzoj 1232: [Usaco2008Nov]安慰奶牛cheer【最小生成樹】

有趣 每條邊在算答案的時候被算了二倍的邊權值加上兩個端點的權值&#xff0c;然后睡覺點額外加一次 所以可以用這個權做MST&#xff0c;然后加上點權最小的點 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N1…

JavaScript --- [學習筆記]觀察者模式 理解對象 工廠模式 構造函數模式

說明 本系列(JS基礎梳理)為后面TCP的模擬實現做準備本篇的主要內容: 觀察者模式、工廠模式、構造函數模式 和 對對象的理解 1. 觀察者模式 參考JavaScript設計模式 1.1 消息注冊方法 “將訂閱者注冊的消息推入到消息隊列中” [算法思路] : 在推入到消息隊列時,如果此消息…

java_day19_MVC和配置文件

簡單的MVC設計 MVC的全名是Model View Controller&#xff0c;是模型(model)&#xff0d;視圖(view)&#xff0d;控制器(controller)的縮寫&#xff0c;是一種軟件設計典范。它是用一種業務邏輯、數據與界面顯示分離的方法來組織代碼&#xff0c;將眾多的業務邏輯聚集到一個部件…