DOM (主要是针对元素的 创建,增,删,改,查,属性操作,事件操作..)
1.简介
1.文档对象模型,是W3C组织推荐的处理可拓展标记语言(HTML/XML)的标准编程接口
我们可以通过DOM改变页面中的样式,结构,内容
2.DOM树
.文档:一个页面就是一个文档,DOM中用 document 表示
.元素:页面中所有的标签都是元素,DOM中用 element 表示
.节点:网页中所有内容都是节点(标签节点,属性节点,文本节点,注释节点...),DOM中使用 node 表示
(DOM把以上内容都看做对象)
2.获取元素
1.获取元素的目的就是为了操作元素
2.方式:
.根据ID获取:
getElementById('id')方法获取带有ID的元素对象
(文档中的 ID 必须是唯一的。如果一个文档中有两个及以上的元素具有相同的 ID,
那么该方法只会返回查找到的第一个元素。)
(参数必须是字符串)
.根据标签名获取
getElementsByTagName()方法返回带有指定标签名对象的集合
还可以获取某个元素(父元素)内部指定标签的子元素
父元素必须是指定的单个元素
element.getElementsByTagName('标签名');
eg:
var ol=document.getElementsByTagName('ol');//获取的是一个伪数组,我们需要得 到一个对象,而不是一个数组
var li=ol[0].getElementsByTagName('li');
.通过HTML5新增的方法获取(通过类名)
getElementsByClassName('类名');//获取的是集合
querySelector('选择器');//获取指定选择器的第一个元素对象 .box #nav
querySelectorAll('选择器');//获取的是指定选择器的集合
.获取特殊元素body,html
.获取body元素
document.body;
//获取body元素对象
.获取html元素
document.documentElement;
//获取html元素对象
3.事件基础
0.常用的事件:
鼠标事件:onclick,
onmouseover(鼠标经过),
onmouseout(鼠标离开),
onfocus(获得鼠标焦点),
onblur(失去鼠标焦点),
onmousemove(鼠标移动触发),
onmouseup(鼠标弹起触发),
onmousedown(鼠标按下触发)
1.事件就是触发响应机制
如点击,划过...
2.事件的组成
事件源
事件触发的对象,如 按钮
事件类型
如何触发,什么事件
如 鼠标点击(onclick)
事件处理程序
通过一个函数赋值的方式完成
eg:
<button id="btn">唐伯虎点秋香</button>
<script>
//获取事件源
var btn=document.getElementById('btn');
//绑定事件
btn.οnclick=function(){
alert('点秋香');//添加事件处理程序
}
</script>
4.操作元素
我们可以利用DOM 操作元素来改变元素里面的内容,属性
1.改变元素内容
element.innerText='修该的内容';//不识别html标签
改变元素内容
element.innerHTML='修该的内容';//识别html标签(W3C推荐,使用的多)
改变元素内容
(这两个属性是可读写的,可以获取元素里面的内容
innerText会把读到的内容里面的html标签去掉,空格与换行也会去掉
innerHTML会把读到的完整内容都显示出来,包括里面的html标签,保留空格与换行
)
2.常用元素的属性操作
1.src(图片的路径)
img.src='...';(img是我们获取的图片对象)
2.title(鼠标放在图片上会显示的信息)
img.title='...';
3.表单元素的属性操作
利用DOM可以操作表单的 type,value,checked,selected,disabled(禁用)等属性
1.修改表单里面的内容我们不能用innerHTML了我们用vaule
input.value='点击了';
4.样式属性操作
通过JS修改元素的大小,颜色,位置等样式
1.element.style//行内样式修改,里面的样式采取驼峰命名的规则,权重比CSS大
div.style.backgroundColor='red';
2.element.className//类名样式修改
element.className='新的类名';
//在style中写CSS类选择器,写里面的样式
当我们修改了类名,里面的样式,也变了,适合与样式变化多的
5.自定义属性的操作
1.获取元素的属性值
element.属性;(获取的是元素的内置属性)
element.getAttribute('属性名');(主要获取元素自定义的属性)
2.设置元素的属性值
element.属性='属性值';(设置内置属性值)
element.setAttribute('属性','属性值');(主要设置自定义的属性);
3.移除元素的属性
element.removeAttribute('属性');
6.H5自定义属性
1.自定义属性的目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中
2.H5规定自定义属性为data-开头作为属性名并且赋值:
目的:因为有些自定义属性很容易引起歧义,不容易判断是内置属性,还是自定义属性
3.h5新增的获取自定义属性的方法
<div data-index="1" data-last-name='ldn'></div>
var div=document.querySelector('div');
div.dataset.index;(index就是data-后面跟的名字)
//如果是名字带有-,那么在用该方法获取时,需要把-去掉,并且用驼峰命名的方法代替
div.dataset.lastName;
5.节点操作
1.网页中的所有内容都是节点(标签,属性,文本,注释...),在DOM中,节点用node来表示.DOM树中所有的节点均可通过js进行访问,所有节点均可以被修改,创建,删除
2.节点至少拥有 nodeType(节点类型),nodeName(节点名称),nodeValue(节点值)这三个基本属性
元素节点:nodeType为1
属性节点:nodeType为2
文本节点:nodeType为3(文本节点包括文字,空格,换行....)
(在实际开发中,节点操作的主要是元素节点)
3.父节点: node.parentNode
(得到的是离元素最近的父级节点,如果找不到,返回null),,wpm
4.子节点:
1.parentNode.childNodes(标准)
(得到的是一个集合:得到所有的节点,包括元素节点,文本节点...,
但是我们需要的是元素节点,我们需要结合循环和节点类型来筛选,比较麻烦,所以我们一般不提倡使用childNodes)
2.parentNode.children(非标准,但是得到了各个浏览器的支持,我们可以放心使用)
(直接获取所有的子元素节点,常用)
3.parentNode.firstChild
(返回第一个子节点(并不是元素节点),找不到则返回null,同样,也是包含所有的节点)
4.parentNode.lastChild
(返回最后一个子节点(并不是元素节点),找不到则返回null,同样,也是包含所有的节点)
5.parentNode.firstElementChild
(返回第一个元素节点,找不到则返回null)(有兼容性问题)
6.parentNode.lastElementChild
(返回最后一个元素节点,找不到则返回null)(有兼容性问题)
7.获取第一个子元素和最后一个子元素,我们一般不用上面的,我们一般用第2个
ol.children[0]
ol.children[ol.children-1]
5.兄弟节点
1.node.nextSibling
( 得到下一个兄弟节点,包含元素节点,文本节点...)
2.node.previousSibling
( 得到上一个兄弟节点,包含元素节点,文本节点...)
3.node.nextElementSibing
(得到下一个兄弟元素节点,找不到返回null)
4.node.previousElementSibing
(得到上一个兄弟元素节点,找不到返回null)
(3,4方法有兼容性问题)
6.在页面添加节点
应用场景:评论的发表
1.动态创建元素节点
var element = document.createElement('HTML元素');
2.添加节点:
1.后面追加元素
node.appendChild(child);
2.添加到父节点指定子节点的前面
node.insertBefore(child,指定元素);
7.删除节点
node.removeChild(child);
(删除父元素里面的子元素,并将删除的元素返回)
8.复制节点
node.cloneNode();//浅拷贝
//此时只是克隆了一份,我们需要像添加节点一样,把它添加到指定的位置
//注意:如果()里面为空/false,则为浅克隆,即只复制节点本身,而不复制其子节点
node.cloneNode(true);//深拷贝
9.三种动态创建元素的方式
1.document.write('<div>123</div>');
(一般不用.因为它会导致页面重绘,不是我们想要的)
2.element.innerHTML('<a href="javascript:;">删除</a>');
3.element.createElement('a');//创建a标签
注意:
innerHTML和createElement创建多个元素的效率哪个更高?
innerHTML如果不采用字符串拼接,而采用数组的方式,效率更高
createElement创建多个元素的效率稍微低一些,但是结构更清晰
6.事件高级
1.注册事件(绑定事件)
1.注册事件就是给元素添加事件
2.注册事件有两种方式:
1.传统方式:都是利用on开头的事件
<button οnclick='alert("...")'></button>
evenTarget.οnclick=function(){
....
}
特点:注册事件的唯一性
同一个元素同一个事件只能设置一个处理函数,最后注册的会覆盖前面的
2.方法监听注册事件(W3C推荐的方式,推荐)
特点:同一个元素同一个事件可以注册多个监听器
会按照顺序依次执行
格式:
evenTarget.addEventListener(type,listener [,useCapture])
.evenTarget:监听的对象
.type:事件类型字符串,如click,mouseover(不带on)
.listener:事件处理函数,事件发生时,会调用该监听器
可以用匿名函数,也可以直接在外面写一个函数,然后再调用即可
.useCapture:可选参数,是一个布尔值,默认为false
eg:
btn.addEventListener('click',function(){
alert('222');
}
)
btn.addEventListener('click',fun);//里面的fun后面不需要加()
fun(){
....
}
2.删除事件(解绑事件)
删除事件的方式
1.传统注册方式
evenTarget.οnclick=null;
2.方法监听注册事件
evenTarget.removeEventListener(type,listener [,useCapture]);
3.DOM事件流
1.事件流描述的是从页面接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流
2.DOM事件流分为3个阶段
1.捕获阶段(从大元素到小元素)
2.当前目标阶段
3.冒泡阶段(从小元素到大元素)(我们更看重这个)
3.JS代码只能执行捕获/冒泡的一种阶段
传统方式的注册事件 只能得到冒泡阶段
方法监听注册事件 两个都可以,第三个参数是 true 则是捕获阶段
第三个参数是 flse/不写 则是冒泡阶段
4.事件对象
1.事件对象(e),就是写到我们监听函数的小括号里面,我们当形参来看,但我们不需要传递实参过去
事件对象只有有了事件,才能存在.它是系统自动给我们创建的,不需要我们传递
事件对象是我们事件一系列相关数据的集合,跟事件相关的,比如鼠标点击里面就包含了鼠标的相关信心,鼠标坐标..
div.οnclick=function(e){
...
}
2.e.target(事件对象的属性)和this的区别
e.target返回的是触发事件的对象(元素)
this返回的是绑定事件的对象(元素)
3.事件对象阻止默认行为
eg:让连接不跳转,提交按钮不提交
e.preventDefault();
4.对象事件阻止冒泡
e.stopPropagation();
5.事件委托(代理,委派(在jQuery里面叫委派))
.事件冒泡本身的特性,会带来坏处,但也会带来好处,需要我们灵活掌握
.事件委托的原理:
不是给每一个子节点单独设置事件监听器,而是事件监听器设置父节点上,然后利用冒泡原理影响设置每一个子节点
.事件委托的好处:
我们只操作了一次DOM,提高了程序的性能
5.常用的鼠标事件
1.禁止鼠标右键菜单:
contextmenu:主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
eg:
document.addEventListener('contextmenu',function(e){
e.preventDefault();
})
2.禁止选中文字:
selectstart:
document.addEventListener('selectstart',function(e){
e.preventDefault();
})
6.鼠标事件对象
1. e.clientX
e.clientY
(返回鼠标相对于浏览器窗口可视区的XY坐标)
2. e.pageX
e.pageY
(返回鼠标相对于文档页面的XY坐标,用的多)
(X是鼠标离左边的距离,Y是鼠标离右边的距离)
7.mousemove鼠标移动事件
只有鼠标移动1px就会触发事件
8.常用的键盘事件
onkeyup:
某个键盘按键松开时触发
onkeydown:
某个键盘按键按下时触发
onkeypress:
某个键盘按键按下时触发(但它不识别shift,ctrl,箭头等功能键)
这三个键的执行顺序:
keydown->keypress->keyup
8.键盘事件对象
e.keyCode:返回按键的ASCII码值
//注意:我们的onkeyup,onkeydown事件不区分字母大小写,a和A得到的都是65
// 我们的onkeypress事件区分大小写