一、DOM
①简介
文档对象模型(Document Object Model),是W3C组织推荐的处理可扩展置标语言的标准编程接口。它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和www文档的风格(HTMl和XML文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。
②DOM树
- 文档:一个页面就是一个文档,DOM中使用docum表示
- 元素:页面中所有标签都是元素,DOM中使用element表示
- 节点:网页中所有的内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上内容都看做是对象!
二、获取元素
①通过ID获取:getElementById()
var element=document.getElementById('id');//语法
- element是一个Element对象
- id是大小写敏感的字符串,代表了所要查找的元素的唯一ID
- 返回一个匹配到ID的DOM Element 对象(带标签)
- 若再当前Document下没有找到,返回null
②通过标签名获取:getElementsByTagName()
可以返回带有指定标签名的对象的集合
var element=document.getElementsByTagName('标签名');//语法
- 返回获取过来元素对象的集合,以伪数组形式储存
- 得到的元素是动态的
- 想打印里面的元素可以采取遍历等方式
- 如果页面中只有一个所寻标签,返回的还是伪数组的形式
- 如果页面中没有这个元素,返回的是空的伪数组
- 可以指定获取某个父元素中的子元素
var ol=document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
③通过HTML5新增的方法获取
1.document.getElementsByClassName('类名');//根据类名返回元素对象集合
2.document.querySelector('选择器');//根据指定选择器返回第一个元素对象
3.document.querySelectorAll('选择器');//根据指定选择器返回所有元素对象集合
一些上述方法的效果~
④获取body元素/html元素
//获取body元素
var bodyEle=document.body;
console.log(bodyEle);
console.dir(bodyEle);
//获取html元素
var htmlEle=document.documentElement;
console.log(htmlEle);
效果如下~
三、事件
①概述
JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为。
(触发—响应机制)
网页每个元素都可以产生某些可以触发JavaScript的事件(点击某按钮产生事件,执行某些操作)
②组成部分(事件三要素)
- 事件源:事件被触发的对象(如一个按钮)
- 事件类型:如何触发?什么事件?(比如鼠标点击onclick,鼠标经过,键盘按下 等等)
- 事件处理程序:通过一个函数赋值的方法完成
③执行事件的步骤
- 获取事件源:例如 var div=document.querySelector(‘div’);
- 绑定事件 注册事件:div.onclick
- 添加事件处理程序(函数赋值形式):div.οnclick=function(){console.log('输出');}
下面是一些鼠标事件~
四、操作元素
可以利用DOM操作元素改变里面的内容,属性等
①改变元素内容
element.innerText
//从起始位置到终止位置,但除去html标签,空格和换行也会去掉
element.innerHTML
//从起始位置到终止位置的全部内容,包括html标签,空格和换行
注:元素可以不用添加事件
例如—element.innerText= getDate();
直接赋值,对应元素中的内容直接被覆盖改变!
innerText 和 innerHTML的区别有什么?
1.innerText不识别HTML标签,(非标准),去除空格和换行
2.innerHTML识别HTML标签,(W3C标准) ,保留空格和换行
3.这两个属性可读写,可以获取元素里面的内容
②常用元素的属性操作
- innerText、innerHTML改变元素属性
- src、href
- id、alt、title
③表单元素的属性操作
type、value、checked、selected、disabled
④样式属性操作
修改元素的大小,颜色,位置等样式
- element.style:行内样式操作(样式少,功能简单)
- element.className:类名样式操作(样式多,功能复杂)
修改style样式的做法:
注:
- JS里面的样式采用驼峰命名法(如fontSize)
- JS修改style样式操作,产生的是行内样式,CSS权重比较高
修改类名样式的做法:
- className会直接更改元素类名,覆盖原先类名
- 如果想要保留原类名,可以使用多类名选择器(this.className='原类名 现类名';)
⑤排他思想
一个例子:只有一个最近被点击的按钮有背景色
<body>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<script>
var btns=document.querySelectorAll('button');
//btns得到的是伪数组
for(var i=0;i<btns.length;i++)
{
btns[i].onclick=function(){
for(var j=0;j<btns.length;j++)
{
btns[j].style.backgroundColor='';
}
this.style.backgroundColor='pink';
}
}
</script>
</body>
- 首先清除其他样式
- 随后设置自己样式
⑥自定义属性的操作
1.获取属性值
- element.属性 — 获取内置属性值(元素自带的属性)
- element.getAttribute('属性');— 获得自定义的属性(标准)
2.设置属性值
- element.属性='值';— 设置内置属性值
- element.setAttribute('属性','值');— 主要针对自定义属性(也可修改自带属性)
注意:setAttribute中class属性特殊,写的就是class而不是className!
3.移除属性
element.removeAttribute('属性');
⑦H5自定义属性
1.设置H5自定义属性
H5规定自定义属性data-开头作为属性名并赋值
例如:<div data-index="1"></div>
或使用JS设置:element.setAttribute(‘data-index’,2)
2.获取H5自定义属性
1.兼容性获取:element.getAttribute(‘data-index’);
2.H5新增:element.dataset.index或者element.dataset['index']
(ie11才开始支持)
(只能获取data-开头的)
(dataset是一个存放了所有以data开头的自定义属性)
注:当自定义属性里面有多个-链接单词时,我们获取时采用驼峰命名法
五、节点操作
获取元素有两种方式~
1.利用DOM提供的方法获取元素——逻辑不强,繁琐
2.利用节点层级关系获取元素——逻辑性强,兼容性稍差(更简单!)
①三个基本属性
1.nodeType(节点类型)
- 元素节点:nodeType为1(实际开发中主要操作)
- 属性节点:nodeType为2
- 文本节点:nodeType为3(文字、空格、换行等)
2.nodeName(节点名称)
3.nodeValue(节点值)
②节点层级
利用DOM树可以把节点划分成不同层级关系,常见的是父子兄层级关系
1.父级节点
如何取到?——child element.parentNode
(得到的是离元素最近的父节点)
2.子节点
1.如何取到?——parent element.childNodes(标准)
(得到的是所有子节点的集合,包含元素节点、文本节点等等)
可以用数组的形式取第某个特定子节点,可以用nodeType判断节点类型
2.如何取到?——parentNode.children(非标准)
(这是一个只读属性,只返回所有子元素节点,其余节点不返回)
3.如何取第一个子节点?——parent element.firstChild
4.如何取最后一个子节点?——parent element.lastChild
5.如何取第一个子元素节点?——parent element.firstElementChild
6.如何取最后一个子元素节点?——parent element.lastElementChild
实际开发的写法(既没有兼容性问题又能返回)
第一个子元素parent element.children[0]
最后一个子元素parent element.children[parent element.children.length-1]
3.兄弟节点
1.如何取到下一个兄弟节点?——element.nextSibling
2.如何取到上一个兄弟节点?——element.previousSibling
(包含所有节点,找不到返回null)
3.如何取下一个兄弟元素节点?——element.nextElementSibling
4.如何取上一个兄弟元素节点?——element.previousElementSibling
(仅返回元素节点,找不到返回null)
③创建节点
1.动态创建元素节点:document.createElement(‘tagName’)
2.添加节点:
在后方添加节点:node.appendChild(child)
(将一个节点添加至指定父节点的子节点列表末尾,其中node父级 child子级,后面追加元素,类似于数组中的push和CSS中的after伪元素)
在前面添加节点:node.insertBefore(child,指定元素)
(将一个节点添加至指定父节点的指定子节点前面,类似于CSS中的before伪元素)
④删除节点
node.removeChild(child)——从DOM中删除一个子节点,返回删除的节点
⑤复制节点(克隆/拷贝节点)
node.cloneNode()——返回调用该方法的节点的一个副本
注意:
- 如果括号参数为空或者false,则是浅拷贝,只复制标签不复制里面的内容
- node.cloneNode(true):深拷贝,复制节点及里面所有子节点
⑥三种动态创建元素
1.document.write()
- 里面是带标签的元素,如‘<div>123</div>’
- 直接将内容写进页面文档流
- 文档流执行完毕再调用它,则会导致页面全部重绘(原内容不保留,创建新的<html>)
2.element.innerHTML
var inner=document.querySelectorAll('.inner');
inner.innerHTML='<a href="#">123</a>'
- 将内容写入某个DOM节点
- 不会导致页面全部重绘
- 创建多个元素效率更高,结构稍复杂
- 不要拼接字符串,采取数组形式拼接
3.document.createElement()
var create=document.querySelectorAll('.inner');
var a=document.createElement('a');
create.appendChild(a);
- 创建多个元素效率稍低一点,结构更清晰
不同浏览器下,innerHTML效率要比createElement高
课后总结
这次的预习中事件这一部分预习的不太到位,少了很多知识点,下面是一些补充~
1.事件冒泡:obj.addEventListener(event,function,useCapture)
其中type是事件类型,function是事件处理函数,useCapture是否在补货或者冒泡中执行(true:将事件绑定在捕获阶段 or false:将事件绑定在冒泡阶段)决定事件处理顺序是由内层元素到外侧元素或相反。(可以一次为元素添加多个事件处理函数)
2.事件流:一个DOM事件被触发会经历一下三个阶段
- 捕获阶段:先由根节点document往事件触发对象,从外向内捕获事件对象
- 目标阶段:到达目的事件位置,触发事件
- 冒泡阶段:从目标事件位置往文档的根节点方向回溯,从内向外冒泡事件对象
顺序:父元素捕获-目标元素事件1-目标元素事件2-子元素捕获-子元素冒泡-父元素冒泡
前提:事件确实落到了子元素布局区域,而不是简单的具有嵌套关系
3.DOM0级2级3级事件
0级:将一个函数赋值给一个事件处理属性
2级:在0级的基础上弥补了一个处理程序无法同时绑定多个处理函数的缺点。
3级:在2级的基础上添加了更多事件类型(UI事件、焦点事件、鼠标事件、滚轮事件、文本事件、键盘事件、合成事件、变动事件)
4.删除事件:element.οnclick=null
5.替换元素:element.replaceChild(newNode,oldNode)
新节点替换旧节点,这个新节点可以是新创建的也可以是某个已经存在的节点