术语
库
- 我们把提供给其他人用的工具代码叫做库
- 比如jQuery、Underscore
API
- 库暴露出来的函数或属性(应用编程接口)
框架
- 当你的库变得很大,并且需要学习才能看懂,那么这个库叫做框架,比如Vue/React
两种封装风格
对象风格
- 也叫命名空间风格
- window.dom是我们提供的全局变量
增
- document.creat(
<div>hi</div>)用于创建节点 - dom.after(node,node2)用于新增弟弟
- dom.before(node,node2)用于新增哥哥
- dom.append(parent,child)用于新增儿子
- dom.wrap(
<div></div>)用于新增爸爸
实操
搭建环境
创建1个div
- window.dom是全局对象,Create 是属性名,对应着相应的函数
- create只是方便理解的属性名字,可以任意取,但是tagName是参数名,不能变
- create函数,可以写在里面:
create: function(tagName) { return document.createElement(tagName); } - 也可以写在外面:
dom.create = function(tagName) - 小结:函数包含着dom指令,函数类比成全局对象的某个属性,参数不能变,但是属性名可以自由发挥,只要调用属性的时候对的时候对得上就可以了
- 定义一个div,调用create属性对应的函数,函数执行dom操作,传参,参数为'div',即tagName
- 初步实现功能,新增一个div
变化! 能不能在div里面创建span<div><span>1</span></div>
- 把
<div><span>1</span></div>作为参数?
- 引入一个container,属性依然是创建div
- container传入的字符传入HTML
- 返回container的第0个对象,即div
- 调用函数,注意此时的参数是代码组成的字符创
但是有BUG!
- 如果输入参数,标签tr,td,无法实现效果,应为要在table标签里面
使用template标签,它是能容纳所有标签的标签
- string加trim(),防止参数前面有空格,拿到了文本,所以这是直接去掉字符串两边空格的
- return的写法严格按照如图方式,否则出错
- console.log()参数div不影响结果
新增一个弟弟 after,
- 定义after属性,函数参数node,node2,将node2放到node的下一个节点的前面
- insert只有before,没有after
- 找到node的父级,在node的下一个节点插入到node2的前面
如果node是最后的节点,没有下一个节点,依然可以实现功能
新增一个哥哥
- 思路同上,常规DOM指令,调用指令常规
新增一个儿子
新增加一个父级元素
- 如图二,要将div3,放到div2外面
- 先将div3放在div2的前面或者后面
- 然后将div2,放到div3里面,div2原地消失
删除节点
- 找到父级元素然后删除子代元素
删除后代
- 为了删除子代,但是返回被删除的子代,所以用到循环
- 不能用foe循环,应为i<node.length,但是长度随着删除元素而变化,所以不能用
- while循环:引入空数组array,用来存放被删除的子代元素
- 引入x,让x等于node的第一个子元素
- 进入while循环,array数组里面逐个放入node删除的第一个子元素,remove函数已经在上面写好,可以直接用
- x 再次赋值,等于node的第一个子元素,因为第一个子元素删除,后面的元素替补作为第一个子元素
- 循环条件while(x),当x为空,那么表明node里面的元素被删光了,循环停止
- 返回array数组,可以查看被删除的部分,里面的节点除了标签,还有文本节点,这些文本节点是回车键
增加属性以及内容
- 这是详细的写法,重载
- 如果接受三个参数,就是写入属性名,属性值
- 如果接受两个参数,就是得到属性名
- 调用函数,写入title属性,属性内容
- 引入变量title,得到title属性
- 打印出title属性的内容
标签里面增加文本内容
- 但是有个问题,里面的内容会让元素的子元素全部消失
- 所以在实际开发中,对于要更改的内容,标签里面加id,避免这种情况发生
适配版本
- innerText兼容IE
- textContet适配chrome,firefox
- 条件判断,这种方法叫做适配
读写html内容
- 判断适配
- 如果2个参数,那么就是写入内容
- 如果是一个参数,那么就返回内容,读写参数
添加样式
- 根据调用时提供的参数数量、类型进行的判断
- 如果是三个参数 如
dom.style(div,'color','red'),那么 写入样式 - 如果是两个参数,分两种情况讨论,判断第二个参数数据类型
- 如果第二个参数是字符串,如
dom.style(div,'color'),那么就是获取color属性 - 如果第二个参数是对象,让node里面的key与对象里面的key一一对应,写入对象里面涉及的属性
添加、删除、判断class
- 三个功能,写在class对象里面
- 最后一个判断,要return,返回值,调用的时候加console.log,即可判断是否有相应的属性
添加/删除事件监听
- 注意调用思想
查找元素
- 提供选择器,返回所有符合条件的元素组成的数组
- 调用的时候加【0】,应为要得到对象,所以从数组里面调用
如果test里面有子元素,查找范围不同呢
- 如果一个参数,就在document里面寻找元素
- 如果两个参数,就在scope里面调用queryselector,||(或)用法
- 思想:查找的节点不同
找到父级元素、子级元素
找到同级元素
- 三种思想
- 找到父级元素的子级元素
- 过滤自己,条件是n等于传入的node,过滤掉
- node.parentNode.children,返回的是伪数组{xxx,xxx,xxx,xxx},Array.from转化成数组
- 调用的时候还是加【0】结尾
找到后面一个节点(弟弟)
- 思路;下一个节点可能是文本
- 引入变量x等于下一个节点
- while,条件,x存在并且x的属性是文本节点,x等于自己的下一个节点
- 循环结束,返回x
遍历所有的节点
获取排行老几
- 注意let i的位置,考虑作用域问题