硬核封装DOM

117 阅读2分钟

我在进行封装dom时认为以下几点需要分析

疑问1:

为 node 添加父节点parent时为什么不直接添加?

  • 若直接执行 dom.append(parent, node) ,其实是会报错的
  • 应该先让 parent 在页面中有个位置,再进行添加
  • 不能凭空出现一个parent
wrap(node, parent){
    dom.before(node, parent)
    dom.append(parent, node)
  }

疑问2:

删除 node 的孩子时为什么总是删除第一个孩子?

  • 当你使用 for 循环遍历所有孩子并删除时,你会发现lenght是实时变化的,因此这种做法有误!
  • 换一种思路
  • 把 node 的第一个孩子给 x ,判断 x 是否存在,存在就删去
  • 这时 node 已经更新,又把 node 的第一个孩子给 x,直到 x 不存在返回存入 node 的孩子的数组。
 empty(node){
    const array = []
    let x = node.firstChild
    while(x){
      array.push(dom.remove(node.firstChild))
      x = node.firstChild
    }
    return array
  }

3 分析以下代码:设置/查看 node 的 style 属性 重载+适配

style(node, name, value){
    if(arguments.length===3){       //参数为3个时,设置style属性
      // dom.style(div, 'color', 'red')
      node.style[name] = value
    }else if(arguments.length===2){
      if(typeof name === 'string'){     //参数为2个并且name是字符串时,查看style属性
        // dom.style(div, 'color')
        return node.style[name]
      }else if(name instanceof Object){     //参数为2个并且name是对象时,设置style属性
        // dom.style(div, {color: 'red'})
        const object = name
        for(let key in object){             //遍历属性
          node.style[key] = object[key]
        }
      }
    }
  }

4 分析以下代码:查找选择器为 selector 的 node

//当 selector 在 scope 节点范围内没找到的话就去整个页面找
find(selector, scope){      
    return (scope || document).querySelectorAll(selector)
  }

5 分析以下代码:查找 node 的兄弟姐妹

//使用 filter 方法过滤掉自己
siblings(node){
    return Array.from(node.parentNode.children)
    .filter(n=>n!==node)
  }

6 分析以下代码:创建节点

  • template:可容纳所有标签
  • trim:把标签两边的空格去掉
  • 返回值要使用content才正确
  create(string) {
    const container = document.createElement("template");
    container.innerHTML = string.trim();
    return container.content.firstChild;
  }
  dom.create("   <div><strong>重要的</strong></div>  ")