00:00
这节课我们来学习手写递归,创建子节点。之前的视频呢,我们已经把这个create element呢,现在呢,已经写了一个,呃,内部是文字的一种情况。那么内部是文字的话呢,非常的简单啊,比如说像这个H,这个H,这四个H啊,都是内部是文字的情况,那么这个时候呢,他就非常的清楚。但是如果像第一个这个H,它里边是个数组的话呢,那这个时候就需要递归对吧?哎,就是它内部是,呃,就是它内部是子节点。子节点,那么就要递归啊,去进行一个创建节点,那么递归的话呢,你要先思考几个事啊,第一个事儿呢,就是它递归的什么时候结束。它不能一直递归,它就死循环了,那递归结束的时候呢,实际上就是当H函数遇见了它是文本,它就不递归。所以你就会发现这里呢,它这是不递归的。
01:04
啊,就刚才是文本是不递归的。第二件事呢,是因为它这个子节点,大家有没有发现,就是他要创建子节点,创建节点的话呢,那不就是这个函数本身吗?所以这里势必就会去调用create element这个函数。但是create element函数呢?它需要提供标杆。啊,有没有发现这个标杆你现在不好用。这个标杆不好用,为什么?因为我们现在比如说要创建abcd,它没有标杆,它是不是就是一个一个的去寻下来。所以他没有标杆,大家发没发现。啊,没有标杆。那没有标杆的话,我们现在要怎么办?对我们现在的话任务呢,其实就是说把这个标杆这个参数给去掉。啊,就让这个函数,咱们现在不要去接受标杆这个参数。哎,给它去掉。就是目这个函数的目的,现在不是把虚拟节点插入到标杆之前了。
02:02
而是现在的这个函数的目的是不是把这个虚拟节点真正的变成盗墓,并且呢,这个虚节点是不是现在还需要添加这个em这个属性。这个大家应该能理解对吧,哎,应该能添加他的elm这个属性。所以我们现在就要改变一下它的这个功能啊,就是说刚才咱们写的这个真正创建节点,它是将beno创建为do,对吧,然后不进行插入啊,但是呢,但是是孤儿节点,但是是孤儿节点,哎,就是不进行插入,插入我们挪到pach里头去进行。发现了吗?挪到patch里头去进行,那这样的话是比较啊比较简单的,一会儿咱们看,所以这个目的就没了。目的没了的话,那这块插入节点就没有这个目的了,我们就删掉。好,那我们现在再恢复成咱们刚才第一个例子,咱们刚才第一个那个例子是什么来着。
03:04
第一个那个例子啊,咱们给它退回去,因为这块递归,你现在发现它代码呢,就这个拟好,哎,它不方便递归的这个函数,哎,那现在这个拟好就出不现了,就等于说上节课上个视频写的,我们又给它拆的拆了一点点。啊,但是别着急,马上就好。所以现在的话,你看我调用这个函数,现在不是同一个节点,我要暴力插入新的,删除旧的。对吧,那这个时候他就不需要提供标杆了。那这个函数的目的是什么?是不是创建出了这个节点了?但是这个节点现在你有没有发现少了一些东西,少了什么?它是引用类型值,所以可以改。哎,是不是就相当于它的补充他的那个em呀。对吧,因为他要把他em给创建出来。对吧,Elm啊属性,所以它的elm属性是什么呢?是不是就是一个domnode呀,就我刚才创建的这个domno,把它补充上来。
04:03
那所以说这个em不就是它的一个真正的道节点吗?这个函数它需要有个返回值。啊,就需要给这个create element返回它。那这个返回是非常关键的,为什么?因为一会儿你要在这里递归。我一旦递归的时候呢,它必须要用到上一次啊,调用这个create element就是递归时候的返回值来做下一次的嫁衣。啊,就是前一次的这个函数的返回值,要做下一次的一个啊,调用的时候的一个参数,因为你要创建出来,不断的创建,所以这个函数返回出来,那它返回的这是什么?它是一个纯倒呀。对吧,Erm属性是一个纯倒的一个对象。那这个纯盗墓对象,你看现在就可以在这里,是不是就可以拿到你这个新节点。对吧,所以这个就是new vno的那个盗墓啊,或者叫elm,就这个是盗墓,那这个东西现在它是没有上树的,它是孤现在是没有看见的,对咱们在这里呢去插入对吧,在这里插入到老节点之前。
05:18
哎,那我们怎么办?对,我们就要用oldinno,那注意看oldinno它是不是就elm的。啊,就咱们刚才里边写的那句话,The parent note。对吧,我们要去insert before。哎,我们要去insert before一下。啊,In色的比一下。那我要insert before什么呀,对,我现在是不是就需要insert before啊,就插入干嘛,我现在要干嘛,插入老节点之前要干什么,是不是要把这个节点给他插入就行了。对吧,但是这个节点它是一定要当标杆啊,因此比如说这是个标杆,你看以这个节点为标杆,插入这个节点,那现在这个你好就能上树了。
06:07
等于说我们现在呢,对create element这个函数进行了一个优化,进行了一个大升级,大改造,那这个改造实际上是为了适应我们的递归的。对吧,哎,我们要去适应咱们这个递归的啊,这个里头就要去适应。所以这样的话呢,咱们这个事情呢,才算是写的啊比较靠谱啊,需要进行一个改造,但是这种改造呢,你一定要理解为什么要改造,就是不要让create element这个函数做太多事情,他如果也负责上述了,那你现在就会发现很乱。为什么乱呢?因为你每次递归的时候,你递归的那一次他也上树了,那不是乱死了吗?对吧?所以这个时候呢,你就需要自己去给他琢磨清楚,但是一会这里有没有open child的呢?有没有追加节点呢?有,为什么这里有open child,因为它很干净,返回一个do,这个do是不是就可以随着你便利children准数组的时候,我们就可以给它end child上去。
07:04
对吧,就相当于他自己在T的情况下不要做太多事儿。因为你这个标杆我不好找,标杆为什么不好找,我去顺序遍历这个盗节点啊,这个子集元素啊,我顺序的时候没有标杆啊,它是aend child的呀,一个一个排下来的呀。没有标杆啊,哪有标杆啊,没有标杆。懂吗?所以我们就把这个标杆拆了。好吧,哎,把这个标杆给它拆掉啊,是这样子的,所以这个大家还是呃挺挺需要关心的,对吧?哎需要注意一下啊,然后咱们现在代码呢,实际上是比较啊多比较啊复杂,所以咱们老师呢,需要在这里配一个G啊,需要配一个G啊,我先把这个点g ignore写上。哎。一个no啊,然后把这个no的modus给加进去啊,配一个G,这样的话,咱们啊,每个阶段,每个阶段它都能存下来。
08:00
对吧,哎,这样子的啊,那配记它的过程就不给大家啊看了啊,咱们嗯,老师快速配一下。好,这个G配置好了啊,这个整个配置过程是没给大家看的啊,咱们视频暂停掉了啊,那现在G配置好了,因为确实太多了,对吧,那现在的话咱们就可以写这个递归了啊,你你只要改造好这个外层节点,它就好变了,如果这个外层节点还有标杆的话,实际上它就不好写。好吧,标杆一定要拿出去啊,拿出去那我们现在就可以便利我们的这个新节点了啊啊,便利子节点,那就是啊,我们现在传入的v note。对吧,哎,它内部的节点啊,The children的length好爱加加。啊,那么你每次遍历的这个子节点呢?我们起个名字都叫做CH。好啊,那这个就是子节点,那我现在可以输出一下这个子节点。
09:02
啊,他这里没有输出,这里没有输出。啊,所以说这个咱们写叫叫做真正的变为倒嘛,咱们就把这把这句话语句写写全叫真正变为倒M对吧?好,但是呢是不插入,但是不插入啊,就是如果是文本节点就不插入。明白吗?就是说如果就是说这个insert比before是在这插入啊,老节点就是最后一个节点在哪插,但是a child的我是可以插入的,所以这个节点它是到底要会不会插入,它是要决定啊,咱们先写完一会再补这句话。好,那这个时候我们测试代码就不能用这个拟好了啊,我们就需要用这个,哎递归,那我这里看一下输出刷新。啊,报错了,报错的原因是因为我这里是不是在这里又需要有个插入啊,对吧,所以这块是不是也需要进行一个判断。大家说呢?
10:00
对吧,哎,这块也需要进行一个判断,因为当我这个节点存在的时候。明白吗?哎,所以这块进行一个判断啊,就是当我这个节点存在的时候,它不是安范的时候啊,因为如果你是安de范的话,那安de范是不能打点调用parent node的,明白吗?哎,所以这块也进行个判断啊,防止他这块再去啊,再去报一个错。哎,就这样的啊,Paranoid啊,就当他的paranoid存在的时候啊,他说para before第一个参数啊,还有new v no v node对吧,哎,是这样子的,就说当它存在的时候啊,且它存在的时候,这个不等于氨fun可以去掉啊就。它存在,且它也存在的时候,好吧,哎,这样它就不报错了,因为我们还没写完,那即使写完了这个也可以加上,那现在它是不是就在循环这些节点,对吧?那现在循环这些节点的话,他要干什么,你大家琢磨琢磨。
11:00
对吧,哎,他要干什么。对,他是不是就需要,因为你只要一递归1CREATE element把它一放进去,那现在它是不是就开始进行创建节点工作,那现在不会死循环。他现在不会死循环。啊,为什么呢?因为你再调用的话,它内部现在是不是就是字符串了。它内部是字符串的话呢,那么现在的话,它就在这里是不递归的。那么现在这个孤儿节点就已经有了,它已经会返回这个孤儿节点了,他就很神奇,所以现在这个是不是就是那个新的那个do。对吧,哎,所以这就是CH的那个do,咱们就管它叫ch do吧。很神奇,那这个ch do是不是就可以追加了?能明白吗?就可以追加到哪里啊对,就可追加到我这个当前上一层的,因为你递归的时候,这是下一层返回的,对吧,当已经返回给你了,你甭管它是第几层递归,就是第N层递归,它会返回给你DN减一层啊。
12:03
所以这一层是不是就可以让v node的ILM是不是就可以end它了?明白吗?就可以end child的,是不是就可以把它给追上来了,因为这个CH盗是上一层返回的erm呀,对吧?哎,那这样的话他就OK,那他他报错了。啊,他说这个是啊,Vno的ER哦,因为你这里还没补它。那这里还没补它对吧,哎,是do veno的啊dono你要补它,然后再去补充这个erm属性。啊,那倒beno的再去补,最后补吧,但是这句话由于是一样的,所以都可以补一下。哎,就放在外头补也行,但是一样的,所以让这个do not追加,那这个就上来了。看见了吗?Abcd又上来了,其实这个abcd上来还是挺有技术含量的。啊,Abcd上来说实话还是挺有技术含量的,因为如果你这个create element没有去策划好,比如说你写上标杆,那标杆的话就没有a pen child了,因为a pen child这个东西呢,它是顺序添加,咱们大家应该知道盗墓上树的时候有两种方法,第一种叫insert before,对吧,第二种叫做a pen child啊,那很明显子元素上树的时候呢,是没有标杆的。
13:22
他没有说插入到谁之前,所以这个时候我们就child。哎,而in before是有标杆的,那我们现在就放在PA中去调用它。看见了吗?就行了。所以现在的话呢,里外里他其实这个时候呢,他他这个时候要做的事情,就思维维度是很高的啊,不要以为这个东西超了你就明白了,因为他的思维维度是很高的。就是这个函数,它还要返回一个em对象,就是它要返回这个do node。哎,要返回这个donode。啊,但是一定要给它补充好啊,返回盗墓no,其实跟返回它是一样的一个对象内存中,呃,引用类型值嘛,内存中同一个对象。
14:04
对吧,是这样子的啊,那么这样的话,你下一层就是第N层掉N加一层的时候,它是不是就会返回一个盗墓对象,这个盗墓对象就可以被aend child就可以被第N层,就是上一层N加一层就可以被第N层,对吧,第N层就可以被N减一层,N减一层可以被N减二层,因为它递归呀,是不是就可以把这个盗墓给它创建回来啊。看见了吗?所以这个create element的写的时候呢,还是挺有技术含量的。啊,所以说这个就是得到,哎得到啊就就是每一个对吧,哎每一个这不是便利吗?哎每一个就是当前,当前这个差children。啊,然后呢,我们现在去创建出它的道,哎,创建出它的道,那么一旦调用create element啊,一旦调用create element意味着什么?对意味着它的em属性呢,就有值了,明白吗?它一定有值了,并且呢,创建出DOM了啊创建出DOM了,并且它这个emm属性就指向了这个DOM,咱们这么写吧。
15:11
哎,并且emm属性,并且它的eml属性就指向了啊,指向了创建创建出的DOM对吧,但是还没有上树,但是还没有上树是一个所谓的孤儿节点,明白吗?哎,这样子的,然后我们在这里去进行上述,那你这个时候肯定就会问老师,这里为什么不上树啊,这里不上树,哎,因为他就说,哎这这个这个文本节点为什么不上述,其实这个设置内部文字不就是相当于上述吗?对吧?设置内部文字不就相当于让文字去上树吗?你能理解吗?但是这个子节点是我父亲直接在这里追加子节点,我的意思是说,为什么内部是文字的时候,他没有把他自己追上数,因为他自己他还是虚拟对吧,那他也就是说他自己是没有N加N减一层的,对,那最后的N减一层是不是在这里追加呢?
16:09
能理解了吧?哎,就很简单,就是说相当于最后一层是在in before这去追加。啊,因为你递归嘛,什么叫递归,咱们可以在这个,呃,咱们可以在process on这去画一下,就到底什么是递归,就是你这一层掉下一层,掉下一层,然后遇见文本节点了,它是不是就会一层一层往回掉。那咱们来看一下啊,就是什么叫递归往下走,他往下走到最后是文本节点了,它是不是就回来了,它是不是就回来了。对吧,那到最后一层,这一层我们是用insert before去做的。这一层我们是iner before,对吧?那么循环递归的时候,我们每一层都是什么啊,End child,当然这块是一个循环啊,A pen child这样去做的。所以这块的话还是挺有技术含量的,大家要好好思考思考,我们标杆放在外头的一个意义啊,好,那这样的话呢,我们这个递归就已经真的实现了啊,你不信的话,咱们可以看一下,把这个C再放一个数组,看见没有,然后这里头再放P。
17:13
啊,再放屁啊,甚至这里头可以再放一个D5,哎,然后D5这里头呢,甚至可以再放一个数组,就它无限层都可以了啊无限层都可以了,那这里呢,就是在H一个OL,比如说有序列表。对吧,哎,然后这里再是数组,然后你看这多少层了力,然后空对象,然后这个是哈哈。对吧,哎,这个是哈哈逗号。哈哈嘻嘻啊,然后这个是么么哒对吧,哎这样子的,那你看刷新看一下没问题吧,这个是盗墓就创建好了。很神奇,很有成就感,有没有发现很有成就感,就是他是ul中的力力力力,然后呢?这个力当中呢,又有div div里头是不是就有OLOL里头是不是就有力力力发现了吗?就非常有成就感啊,它就等于说你递归去创建出了子节子节点。
18:10
所以说你现在有没有发现,这就是咱们之前咱们PPT上说的啊,老师没有骗人啊,就是咱们这节课,就是咱们这次课程是不讲什么知识。哎,咱们这次的课程呢,是不讲把DOM如何变为。虚拟节点的虚拟盗墓的,对吧,但是呢,我们把虚拟节点如何变为盗墓会讲,因为它也是属于拍摄的一部分。你看咱们之前不是说了吗?本次课程研究什么,这不是。老师说老师没骗你们吧,对吧?虚拟盗墓如何通过DF变成真正的盗墓,那事实上虚拟盗墓变成真正盗墓是涵盖在DF算法里面的,因为他比较了两次节点不同,那他这个时候呢,他就需要比较了两个两新老节点不是同一个节点,那他这个时候呢,就会暴力的删除老的啊,然后呢,创建新的,当然咱们现在少一句话,是不是老节点还没有删除啊,对吧?哎,就是删除老节点,删除老节点,所以这个时候就要让old weno的parano去把他自己呢给remove child啊,给它删掉。
19:16
对吧,哎,去把这个O的veno的去给它删掉就行了,那当然是elm啊。删掉就行,所以这块是很简单的。看见了吧,哎,就把它给删掉就行,所以这样的话大家就会发现就是,呃,我们现在这里头就没有那个container了,你要不写这句话呢,Container还在。就特别奇怪啊,它就没了。好吧,哎,就非常的简单啊,那么实际上现在的话呢,你点击按钮它也可以做了,因为你这个ul它也会下掉。你懂吗?就点击按钮它也好了,你说老师真的吗?真的就是你以为你写的很少,实际上现在已经写了很多了。懂吧,诶你已经写了很多了,所以这个时候我们就可以你看再去写一个MENO2对吧,诶MENO2,比如说咱们这回发个section就完全不同对吧?哎,完全不同,然后里头有子节点,子节点里头有H1对吧?啊我是新的H1,然后再去兄弟再来H2吧,好就这样。
20:20
那现在我们就去做点击按钮啊,我们把这个按钮给它得到,我们来看一下这个按钮,这个按钮我们给它得到,那就是b TN on click的时候,我们就可以等于一个function,等于一个function是不是继续排CH啊,对吧?继续排是什么?是不是就是MYVE1和my window2啊。啊,那咱们现在拭目以待,注意看一点是不是变了。有没有觉得觉得很幸福哇,就觉得突然间这个PA就能用了,但是他现在没有进行精细化比较啊,一定记住我们现在在做这个曲线中的哪里,这个图一定要看懂。啊,咱们现在是不是没有在做这个精细化比较对吧,咱们现在就在做这个暴力删除旧的,插入新的,咱们现在就在做这件事,所以这个事是最难的,五角星这件事是最难的,但我们现在还没有涉及,懂了吗?所以一点他是不是暴力删除旧的,删除新的,那为什么能暴力删除旧的?
21:15
为什么能暴力删除九的?对,因为他旧的身上不是已经被补充了em属性吗?大家懂吗?就旧的他已经被补充了elm属性了,所以这个属性就可以被删掉,那为什么能插入新的呀,因为他在递归呀。好吧,哎,所以大家不用特别着急看后边的视频啊,咱们相信老师,你只要现在把这个great element现在写成这样啊,你就会觉得自己的编程水平有了很大的提升啊,就是非常非常稳步提升的,就是大家不用特别着急。好吧,哎,不用特别着急去去这个什么啊,不用特别着急去啊,就是所谓的就是把后边的视频着急看,你先把这个写一写,动手写一写啊,那这样的话啊,你这个编程水平提升是很大的。
我来说两句