createDocumentFragment 妙用

定义和用法

createdocumentfragment()方法创建了一虚拟的节点对象,节点对象包含所有属性和方法。当你想提取文档的一部分,改变,增加,或删除某些内容及插入到文档末尾可以使用

你也可以使用文档的文档对象来执行这些变化,但要防止文件结构被破坏,createDocumentFragment() 方法可以更安全改变文档的结构及节点

在手写 vue 响应式原理中

 // 利用正则表达式来进行查找使用过插值表达式的节点
    const reg = /\{\{(.+)\}\}/
    class Compiler {
      constructor(el, vm) {
        this.el = document.querySelector(el)
        this.vm = vm
        // 进行遍历标签节点,查找出使用插值表达式的 DOM 节点
        this.frag = this._createFragment()
        // 由于上面使用 appendChid 方法将原 dom 树中的节点添加到 DocumentFragment 中会导致节点丢失,所以要把 frag 添加到 el 中
        this.el.appendChild(this.frag)
      }

_createFragment 的实现

  _createFragment() {
        // 创建虚拟节对象(在内存中)
        const frag = document.createDocumentFragment()

        let child
        // 遍历 el 上的所有标签的 DOM 对象
        while (child = this.el.firstChild) {
          this._compile(child)
          frag.appendChild(child)
        }
        // 因为 createDocumentFragment 在内存中创建节点,会导致每添加添加都会丢失之前的 child,所以用 frag 来保存并返回
        return frag
      }

_compile 的实现

 // 进行遍历节点属性来查询使用过插值表达式 {{}} 和 v-model 的节点
      // 如果节点 nodeType === 1 就是标签属性
      // 如果节点 nodeType === 3 就是文本属性
      _compile(node) {
        // 判断当前节点循环出的是不是标签节点
        if (node.nodeType === 1) {
          const attrs = node.attributes
          if (attrs.hasOwnProperty('v-model')) {
            // 当前节点属性是 v-model
            const name = attrs['v-model'].nodeValue
            node.addEventListener('input', e => {
              this.vm[name] = e.target.value
            })
          }
        }
        // 判断当前节点循环出的是不是文本节点
        if (node.nodeType === 3) {
          if (reg.test(node.nodeValue)) {
            const name = RegExp.$1.trim()
            new Watcher(node, name, this.vm)
          }
        }
      }

发现 createDocumentFragment 居然有如此妙用,以上只是部分代码,由于有bug,就不发了(尴尬)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值