BOM&DOM

BOM&DOM

  • 1 DOM
      • 1.1 DOM概述
      • 1.2 DOM树
      • 1.3 查找
      • 1.4 修改
        • 1.4.1 修改内容
        • 1.4.2 修改属性
        • 1.4.3 修改样式
      • 1.5 添加/删除
        • 1.5.1 添加
        • 1.5.2 删除
      • 1.6 HTML DOM常用对象
        • 1.6.1 Image对象
        • 1.6.2 Select/Option对象
        • 1.6.3 Table对象
        • 1.6.4 Form对象
  • 2 BOM
      • 2.1 BOM概述
      • 2.2 Window
      • 2.3 打开和关闭窗口
      • 2.4 history
      • 2.5 location
      • 2.6 navigator
      • 2.6 定时器
        • 2.6.1 周期性定时器setInterval()
        • 2.6.2 一次性定时器setTimeout()
      • 2.7 事件event
        • 2.7.1 事件处理函数
        • 2.7.2 事件模型
        • 2.7.3 事件对象

1 DOM

1.1 DOM概述

DOM: Document Object Model专门操作网页内容的API标准;
W3C统一所有浏览器操作网页内容的API,几乎所有浏览器100%兼容DOM API,用js操作网页内容只能通过DOM API对DOM树操作实现对HTML文档内容的操作
包括:增删改查+事件绑定

常用DOM属性:innerHTML、parentNode、childNodes、attributes

在script标签中window.function(){…}表示当window加载完才自动执行

1.2 DOM树

DOM树:内存中存储一个网页中所有内容的树形结构。树形结构是最直观的表现上下级包含关系的结构。
浏览器读取->自动创建DOM树
1.当浏览器读到一个HTML文件时,会自动在内存中创建唯一树根节点:document
2.浏览器解析HTML中的内容,每读到一项内容,就创建一个节点对象,然后将节点对象添加DOM树上

节点对象:
网页中每一项内容(元素,属性,文本)都是一个节点对象
节点对象node的三个公共属性:

  1. nodeType节点类型,用数字代表该节点对象的类型;无法区分标签名
节点对象类型 数字
document 9
element 1
attribute 2
text 3
注释节点 8
文档声明节点 10
  1. nodeName节点名称
节点对象类型 节点名称
document #document
element 全大写的标签名
attribute 属性名
text #text
注释节点 #comment
  1. nodeValue节点的值(几乎不使用)
节点对象类型 节点的值
document null
element null
attribute 属性值
text 文本内容

绑定事件处理函数:

for (var btn of btns) {
	btn.onclick = function(){
		this.innerHTML="hah";
	}
}

时间处理函数内部this->当前btn,this关键字获得将来触发事件的当前元素本身,直接使用btn会由于btn最终指向btns(全局)的最后一个btn元素而导致所有的修改内容只针对最后一个元素。

1.3 查找

  1. 不需要查找可直接获取的节点:4种
语法 节点类型
document.documentElement html
document.head head
document.body body
document.forms[id/i]
  1. 按节点间关系查找
    节点树是包含所有节点对象的树结构,会受到回车换行以及空字符影响,同样也是节点树的节点#text
语法 含义
node.parentNode 获取node的父节点
node.childNodes 获取node所有直接子节点的集合
node.firstChild 获取node第一个直接子节点
node.lastChild 获取node最后一个直接子节点
node.previousSibling 获取node节点前一个兄弟
node.nextSibling 获取node节点后一个兄弟

元素树是仅包含元素节点的树结构,不包含看不见的空字符,是节点树的子集

语法 含义
node.parentElement 获取node的父节点
node.children 获取node所有直接子节点的集合
node.firstElementChild 获取node第一个直接子节点
node.lastElementChild 获取node最后一个直接子节点
node.previousElementSibling 获取node节点前一个兄弟
node.nextElementSibling 获取node节点后一个兄弟

节点树的childNodes和元素树的children都返回类数组对象,是动态集合(不实际存储属性值,每次访问集合都要重新查找DOM树)
优点:首次查找返回速度快,因为只需要返回指定数据;
缺点:反复访问集合导致反复查找DOM树

遍历父节点下所有后代节点:
1)定义函数,遍历直接子节点
2)对每个直接子节点调用和父元素相同的方法

  1. 按HTML查找
    按元素的HTML特征查找元素
    1)按id查找
    var elem=document.getElementById(“id”);
    只能用document查找,只返回一个元素
    2)按标签名查找
    var elems=parent.getElementsByTagName(“标签”);
    可在任意父元素上调用,返回动态集合,在所有后代中查找
    3)按name属性查找
    var elems=document.getElementsByName(“name”)
    专门查找表单中的元素,只能用document调用,返回动态集合
    4)按class属性查找
    var elems=parent.getElementsByClassName(“class”)
    在任意父元素上调用,返回动态集合,在所有后代中查找,如果一个元素有多个class修饰只需要其中一个class就可找到该元素
  2. 用选择器查找复杂的条件
    1. 只查找一个元素
      var elem=parent.querySelector(“选择器”);
    2. 查找多个元素
      var elems=parent.querySelectorAll(“选择器”);
      可在任意父元素上调用,返回非动态集合(实际存储属性值,即使反复访问集合也不会导致重复查找DOM树,首次查找慢)

按HTML查找和按选择器查找:

  1. 返回值:
    按HTML查找返回动态集合: 不实际存储属性值,每次访问集合都重新查找DOM树
    按选择器查找返回非动态集合: 实际存储完整属性值,每次访问集合不需要重复查找DOM树
  2. 首次查找效率:
    按HTML查找,效率高!
    按选择器查找,效率低
  3. 易用性:
    按HTML查找功能单一
    按选择器查找,功能强大,代码简洁

总结: 查找优化
1.如果用一个条件就可找到元素时,首选按HTML查找
2.如果查找条件复杂时,首选按选择器查找

1.4 修改

1.4.1 修改内容

  1. 原始HTML片段:
    elem.innerHTML 可获取或设置元素开始标签到结束标签之间的HTML片段
  2. 纯文本内容:
    elem.textContent 可获取或设置元素开始标签到结束标签之间的纯文本内容
    比innerHTML多做两件事:
    1.去掉内嵌的标签
    2.转义字符翻译为正文
  3. 表单元素的值: elem.value
    因为表单元素一般为单标记

1.4.2 修改属性

  1. HTML标准属性: HTML标准中规定的属性,有两种方法修改
    1. 核心DOM API: DOM最初指定的可操作一切结构化文档(HTML和XML)的API,可操作任何出现在元素开始标签中的属性
      4个API:
      elem.getAttribute(“属性名”)
      elem.setAttribute(“属性名”,”值”)
      elem.removeAttribute(“属性名”,”值”)
      elem.hasAttribute(“属性名”)
    2. HTML DOM: 专门针对HTML中固定的属性,提供的简化版API
      HTML DOM提前将HTML规定的标准属性都定义在了元素对象上,可用.直接访问
      elem.属性, class属性冲突:elem.className
  2. 状态属性: 4个:
    enabled disabled selected checked 值都是bool,不能通过修改字符串修改值(因为"true"和"false"都会显示为true)
    不能用核心DOM 4个API,只能用HTML DOM的.访问elem.enabled=true/false
  3. 自定义扩展属性:
    HTML标准中没有规定的,开发人员根据业务需求自行添加的属性(实现class中样式属性与自定义事件处理分离,互不干扰)
    1.可用于在客户端临时缓存业务数据:
    2.代替id,class,元素等选择器用于选择元素并绑定事件
    1. 定义自定义扩展属性
    2. 获取或修改自定义扩展属性
      1)用核心DOM修改
      elem.getAttribute(“data-属性名”)
      elem.setAttribute(“data-属性名”,”值”)
      elem.removeAttribute(“data-属性名”)
      elem.hasAttribute(“data-属性名”)
      不能用HTML DOM访问
      2)HTML5自动将所有data-开头的自定义扩展属性收集到elem.dataset属性中
      elem.dataset.属性名 属性名不用加data-前缀
      3)定义扩展属性查找元素:属性选择器:[data-属性名=值]

1.4.3 修改样式

  1. 修改
    elem.style.css属性=”值”,相当于只能修改内联样式属性
    css属性名去横线变驼峰命名法
    问题: 一次只能修改一个css,代码繁琐
    解决: 尽量用class,批量修改元素的样式
    elem.className=”class名”
    elem.className=””
    也可以使用elem.style.cssText对elem写入css样式
  2. 获取
    不能使用elem.style.css属性 仅能获得内联样式
    正确: 获得计算后的样式: 2步:
    1.获得计算后的所有样式的对象:
    var style=getComputedStyle(elem)
    2.获得style中的属性: style.css属性
    计算后的样式,是只读的,不能修改!来源不确定

不要求:如果需要修改样式表中的共享样式
获得网页中的样式表对象
var sheet=document.styleSheets[i];
获得样式表对象中的规则
var rule=sheet.cssRules[i];
//如果是修改keyframes中的css属性则还要找下级cssRule:var subRule=rule.cssRules[i]
修改规则中的css属性:rule.style.css属性=值

1.5 添加/删除

1.5.1 添加

  1. 创建新的空元素
    var a=document.createElement(“a”) ->
    只能由document.createElement创建新元素,属于document特有的API
  2. 设置关键属性
    a.innerHTML=""
    a.href=“http://tmooc.cn”
  3. 将新元素添加到指定父元素下
    parent.appendChild(elem) 将elem追加到parent的最后一个子元素之后
    parent.insertBefore(elem,child2) 将elem插入到parent的子元素child2之前
    parent.replaceBefore(elem,child1) 用elem代替parent的子元素child1的位置

优化: 尽量减少操作DOM树的次数。因为每修改一次DOM树,都会导致重排重绘。
HTML加载过程:
html -> DOM Tree;css -> COM
共同生成RenderTree -> layout -> paint

具体优化方式:

  1. 如果同时添加父元素和多个子元素,应该先在内存中,将所有子元素添加到父元素后,再最后一次性将父元素添加到DOM树
  2. 如果父元素已经在页面上,要添加多个平级子元素:
    使用文档片段(内存中,临时保存多个平级子元素的虚拟父元素)
    1)创建文档片段对象:
    var frag=document.createDocumentFragment();
    2)将多个子元素临时加入到文档片段中:
    frag.appendChild(child)
    3)将frag整体加入到DOM树的父元素下
    parent.appendChild(frag)
    frag将子元素添加到页面后会自动释放

1.5.2 删除

删除: parent.removeChild(child)
child.parentNode.removeChild(child)

1.6 HTML DOM常用对象

1.6.1 Image对象

Image:代表页面上的<元素
简化创建:var img=new Image();只有Image和Option可以通过new的方式来创建,其他对象只能通过document.createElement("")创建;

1.6.2 Select/Option对象

Select:代表页面上的