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.mzph.cn/news/250409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模块单元学习笔记(日志记录模块os模块sys)

一、日志记录模块 Logging 默认情况下&#xff0c;logging将日志打印到屏幕&#xff0c;日志级别大小关系为&#xff1a;CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET&#xff0c;当然也可以自己定义日志级别。 DEBUG&#xff1a;详细的信息,通常只出现…

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 …

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;无论存放…

salesforce lightning零基础学习(三) 表达式的!(绑定表达式)与 #(非绑定表达式)

在salesforce的classic中&#xff0c;我们使用{!expresion}在前台页面展示信息&#xff0c;在lightning中&#xff0c;上一篇我们也提及了&#xff0c;如果展示attribute的值&#xff0c;可以使用{!v.expresion}展示信息。 lightning在component中解析动态值的时候&#xff0c;…

网络协议各层概述

网络协议概述 OSI是一个开放性的通信系统互连参考模型&#xff0c;他是一个定义得非常好的协议规范。OSI模型有7层结构&#xff0c;每层都可以有几个子层。 OSI的7层从上到下分别是 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层&#xff1b; 其中高层&…

javascript --- 实现对象的深拷贝

浅拷贝和深拷贝 浅拷贝: 只拷贝一层.当对象是复杂数据类型(Object、 Array)时,只拷贝引用深拷贝: 多层拷贝.复杂数据类型,会重新分配内存空间. 实现浅拷贝的2种方法 使用for ... in 实现 var obj {name: marron,age: 18,msg: {sex: "1" } } var o {}; for(let …

Qt与FFmpeg联合开发指南(二)——解码(2):封装和界面设计

与解码相关的主要代码在上一篇博客中已经做了介绍&#xff0c;本篇我们会先讨论一下如何控制解码速度再提供一个我个人的封装思路。最后回归到界面设计环节重点看一下如何保证播放器界面在缩放和拖动的过程中保证视频画面的宽高比例。 一、解码速度 播放器播放媒体文件的时候播…

Bzoj1051 受欢迎的牛

每一头牛的愿望就是变成一头最受欢迎的牛。现在有 N 头牛&#xff0c;给你 M 对整数 (A,B)&#xff0c;表示牛 A 认为牛 B 受欢迎。这种关系是具有传递性的&#xff0c;如果 A 认为 B 受欢迎&#xff0c;B 认为 C 受欢迎&#xff0c;那么牛 A 也认为牛 C 受欢迎。你的任务是求出…

javascript --- 文件上传即时预览 闭包实现多图片即时预览

使用javascript原生功能实现,点击上传文件,然后再网页上显示出来 1. 初级显示 1.1 准备一个input标签和一个img标签 <input typefile id"file"> <img id"preview" src"">1.2 js代码如下 // 将上传的图片显示到页面上function sho…

第一次作业:深入Linux源码分析进程模型

一.进程的概念 第一&#xff0c;进程是一个实体。每一个进程都有它自己的地址空间&#xff0c;一般情况下&#xff0c;包括文本区域&#xff08;text region&#xff09;、数据区域&#xff08;data region&#xff09;和堆栈&#xff08;stack region&#xff09;。文本区域存…

关于模型验证那点事儿

今天应笑笑老师之问&#xff0c;做了一个模型验证的例子&#xff0c;发现之前对这个东西的理解太片面&#xff0c;重新整理了一下思路 字段验证优先级高于类验证 什么是类验证呢&#xff1f;就是两个字段组合的验证&#xff0c;比如你Admin不允许修改密码&#xff0c;你修改密码…

Win10安装MySQL5.7.22 解压缩版(手动配置)方法

1.下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/5.7.html#downloads 直接点击下载项 下载后&#xff1a; 2.可以把解压的内容随便放到一个目录&#xff0c;我的是如下目录&#xff08;放到C盘的话&#xff0c;可能在修改ini文件时涉及权限问题&#xff0c;之后我…

Elemant-UI日期范围的表单验证

Form 组件提供了表单验证的功能&#xff0c;只需要通过 rules 属性传入约定的验证规则&#xff0c;并将 Form-Item 的 prop 属性设置为需校验的字段名即可。但是官网的示例只有普通日期类型的验证&#xff0c;没有时间范围的验证。 一开始&#xff0c;我认为时间时间范围的是一…

node --- [express项目] 开发环境下使用morgan控制台输出访问信息

说明 源代码记录、遗忘回顾 process.env node中提供了一个process.env接口用于访问计算机中的系统环境变量. 可以利用以上属性来区分当前的环境是开发环境还是生产环境,代码如下: if (process.env.NODE_ENV development) {console.log(当前环境是开发环境) } else {consol…

Dynamics CRM 访问团队的使用

访问团队和负责人团队的区别是&#xff1a;负责人团队可以拥有记录&#xff0c;访问团队不能拥有记录也不能加入解决方案中。 访问团队用法1&#xff1a;可以将不同组织的人员加入到访问组实现数据的更新、删除、共享 访问团队用法2&#xff1a;访问团队模板的使用 步骤一&…

node --- [express] cookie/session 机制与 中间件的使用(路由守卫)

说明 源代码记忆、遗忘回顾使用 cookie/session 机制,让 客户端/服务器 的访问变得有状态 cookie 与 session 由于 HTTP 协议的无状态性,当一次连接断开后. 服务器并不会记录用户是否登录. 因此需要引入 cookie/session 机制 cookie cookie: 浏览器在电脑硬盘中开辟的一块空…

02 数据类型

转载于:https://www.cnblogs.com/theoup/p/9875293.html

(数据科学学习手札30)朴素贝叶斯分类器的原理详解Python与R实现

一、简介 要介绍朴素贝叶斯&#xff08;naive bayes&#xff09;分类器&#xff0c;就不得不先介绍贝叶斯决策论的相关理论&#xff1a; 贝叶斯决策论&#xff08;bayesian decision theory&#xff09;是概率框架下实施决策的基本方法。对分类任务来说&#xff0c;在所有相关概…

Shiro身份认证---转

目录1.Shro的概念2.Shiro的简单身份认证实现3.Shiro与spring对身份认证的实现前言&#xff1a; Shiro 可以非常容易的开发出足够好的应用&#xff0c;其不仅可以用在 JavaSE 环境&#xff0c;也可以用在 JavaEE 环境。Shiro 可以帮助我们完成&#xff1a;认证、授权、加密、会话…

css --- [练手小项目]样式小结(字体、颜色的语义 清除浮动的使用)

说明 源代码 1.1 CSS属性书写顺序(重点) 建议遵循以下顺序: 1.布局定位属性: display / position / float / clear / visibility / overflow (建议display第一个写, 毕竟关系到模式) 2.自身属性: width / height / margin / padding / border / background 3.文本属性: co…