文章目录
- JavaScript DOM操作
- DOM操作元素
- DOM查询
- 修改元素内容/属性
- 获取元素节点
- DOM的增删改
- DOM操作CSS
- 内联样式
- 获得当前正在显示的样式
- DOM的事件操作
- 事件对象
- 事件对象的属性
- 事件的冒泡和事件的委托
- 事件冒泡
- 事件委派
- 事件的传播
- 事件的绑定
JavaScript DOM操作
DOM操作元素
DOM全程Document Object Model文档对象模型。
文档表示的是整个的HTML网页文档;
对象表示将网页中的每一个部分都转换成了一个对象;
模型来表示对象之间的关系(DOM树),方便我们获取对象。
节点:网页中的每个部分都是一个节点
- 文档节点:整个HTML文档,一个页面就是一个文档
- 元素(标签)节点:HTML文档中的HTML标签
- 属性节点:元素的属性
- 文本节点:HTML标签中的文本内容
浏览器加载一个页面时,是按照自上向下的顺序加载的,读取一行就运行一行
DOM查询
Document对象
实际上是window对象的属性。
代表整个网页,相当于dom树的入口,提供给我们查询节点。
这个对象的独特之处是唯一一个既属于BOM又属于DOM的对象。
修改元素内容/属性
innerText属性 获取到元素内部的文本内容,会自动将html标签去除
innerHTML属性 获取到元素内部的文本内容,会保存html标签
修改元素属性
修改元素属性
1.获取到元素节点对象
2.通过元素节点对象的属性( .或者[] )修改,
方法 | 不同点 |
---|---|
对象.属性 | 1.获取的是内置属性 2.class属性需要使用 元素.className |
element.getAttribute(属性名) element.setAttribute(属性名.值) element.removeAttribute(属性名) | 1.既可以获取/修改/删除内置属性,也可以获取/修改/删除自定义属性 2.class属性直接用class |
获取元素节点
获取的一组DOM对象都是伪数组
通过document对象调用
语法 | 描述 |
---|---|
document.getElementById(“id”) | 通过id获取dom |
document.getElementsByClassName(“className”) | 通过类名获取domdocument.getElementsByName() |
document.getElementsByTagName() | 通过标签名获取一组节点对象 |
document.querySelector(css选择器) | 该方法会返回唯一的一个元素节点 |
document.querySelectorAll(选择器) | 返回数组。 |
获得元素节点的子节点,通过具体的元素节点调用
//id=x节点的下一个子元素节点是id=y的节点。下一个节点是yyy的文本节点
<li id='x'>xxx</li>yyy<li id='y'>zzz</li>
语法 | 描述 |
---|---|
element.getElementsByTagName() | 返回element指定标签名的一组后代节点 |
element.childNodes 属性 | element的所有子节点((
|
element.children 属性 | element的所有子元素节点(
|
element.firstChild 属性 | element的第一个子节点,包括空白文本结点 |
element.firstElementChild属性 | element的第一个子元素节点 |
element.lastChild 属性 | element的最后一个子节点 |
获取父节点和兄弟结点,通过具体的节点调用
语法 | 描述 |
---|---|
element.parentNode 属性 | 表示当前节点的父节点 |
element.previousSibling 属性 | 表示当前节点的前一个兄弟节点,可能会获取到空白文本 |
element.previousElementSibling 属性 | 表示当前节点的前一个兄弟元素节点 |
element.nextSibling 属性 | 表示当前节点的后一个兄弟节点,可能获取到空白文本 |
element.nextSiblingElement 属性 | 表示当前节点的后一个兄弟元素节点 |
获取body/html标签元素
获取bodydocument.body
获取htmldocument.documentElement
DOM的增删改
语法 | 描述 |
---|---|
document.createElement(标签名) | 用于创建一个元素节点对象,并返回创建好的对象 |
document.createTextNode(文本内容) | 根据内容创建文本节点,并返回新的节点 |
父节点.appendChild(子节点) | 向一个父节点中添加新的子节点 |
父节点.insetBefore(新节点,旧节点) | 在指定的子节点前插入新的子节点,父节点调用,对于父节点来说才有子节点 |
父节点.replaceChild(新节点,旧节点) | 使用指定的子节点替换已有的子节点 |
父节点.removeChild(子节点) | 删除一个子节点 |
DOM操作CSS
内联样式
语法
元素.style.样式名 = 样式值
说明
1.如果css的样式名中含有-,需要改成驼峰命名法。
2.通过style属性设置/读取的样式都是内联样式,内联样式有很高的优先级。
3.通过style属性来修改元素的样式,每修改一个样式,浏览器需要重新渲染一次页面
js中常用驼峰命名法(js中-可以代表减号),css和html常用 -
获得当前正在显示的样式
只有ie浏览器支持: 元素.currentStyle.样式名
其他浏览器:window.getComputedStyle(获取样式的元素,伪元素/null)
返回值是当前元素对应的样式的对象
如果该样式没设置,获取到的是真实值而不是默认值
通过以上两种方式获取到的样式都是只读的,如果需要修改只能使用style属性
如果要同时修改多个样式,可以新写一个类的样式,直接通过修改节点的类名
处理兼容性问题
定义一个函数来获取指定元素当前的样式,参数obj要获取样式的元素,style要获取的样式名字符串
function getStyle(obj,style){
if(window.getComputedStyle){
//正常浏览器有getComputedStyle方法
return getComputedStyle(obj,null)[style];
}
else{
//IE8浏览器没有定义getComputedStyle
return obj.currentStyle[style];
}
}
注意
if里面用getComputedStyle不行,要用window.getComputedStyle
没使用window时getComputedStyle是一个变量需要去作用域中寻找,没定义就是用会报错,后续代码不会执行
使用window之后属于属性,没找到属性返回undefined
DOM的事件操作
事件对象
当事件的响应函数被触发时,浏览器每次都会将一个事件对象(event)作为实参传递给响应函数,封装当前事件相关的一切信息,比如:鼠标坐标,键盘哪个键被按。
但是IE8不会传,事件对象作为window对象的属性保存的window.event
可以使用 event = event || window.event 来解决兼容性问题
事件对象的属性
event.clientX:可以获取鼠标指针的水平坐标,返回数值,不带单位
event.clientY:可以获取鼠标指针的垂直坐标,返回数值,不带单位
假设下图左上角为(0,10)
event.clientX/event.clientY用于获取鼠标在当前的可见窗口的坐标,左上角为(0,0)
event.pageX/event.pageY获取鼠标相对于当前页面(document)的坐标,左上角为(0,10)
position是相当于整个页面,左上角(0,10)
event.wheelDalta 获得滚轮的方向 正向上滚,负向下滚
event.target 触发事件的对象
event.keyCode 获取按键的编码 event.altKey/ctrlKey/shiftKey判断alt/ctrl/shift是否被按下
现在浏览器的滚动条都是html的了
事件的冒泡和事件的委托
事件冒泡
同一片区域,给其中的元素都绑定了点击事件,点击公共区域时,触发顺序?
假设如图,从span->box1->body依次触发
事件的冒泡(Bulle):事件的向上传导,事件在目标元素处理后,会由内向外的一层层传递
在开发中大部分情况冒泡都是有用了,如果不需要可以通过事件对象event.cancelBubbl
取消冒泡。
let span = document.getElementById("span ");
span.onclick = function(event){event = event || window.event;//取消冒泡event.cancelBubbl = true;
}
事件委派
场景
1.有很多个超链接,我们为每一个超链接都绑定了单击相应函数,这种操作比较麻烦。
2.如果有个按钮,点击之后可以新加超链接,此时循环绑定在a上的点击事件,新加的超链接里面并没有
我们希望,只绑定一次事件,即可用用到多个元素上,即使元素是后添加的
将其绑定给祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的相应函数来处理事件。
事件委派利用了冒泡,通过委派可以较少事件绑定的次数,提高程序的性能
冒泡从内到外向上冒泡,委派从外到内向下委派。
上述的场景中,我们把事件绑定在ul上,但是点击整个绿色的区域都会触发。
ul.onclick = function(event){
//如果触发事件的对象是我们期望的元素,则执行。否则不执行
event = event ||window.event;
//IE浏览器用event.srcElement
let target = event .target || event .srcElement;
//nodeName节点名称是大写,转换小写再做笔记
if(target.nodeName.toLowerCase == "li"){//触发事件的对象//这里可以分别为每个id设置不同的操作switch(target.id){case 'add':alert('添加');break;case 'remove': alert('删除');break;}}}
事件的传播
W3C将事件传播分为三个阶段
1.捕获阶段,从外层的祖先元素向目标元素进行事件捕获,默认此时不会触发事件
2.目标阶段,事件捕获到目标元素,捕获结束,目标元素触发事件
3.冒泡阶段,事件从目标元素向其祖先元素传递,依次触发祖先元素上的同一事件。
事件的绑定
对象.事件 = 函数
绑定响应函数,同时只能为一个事件绑定一个响应函数,后面的响应函数会覆盖前面的响应函数。
对象.addEventListener()
可以为事件绑定多个响应函数
参数:
1.事件的字符串,不用添加前面的on
2.回调函数,当事件触发时该函数会被调用
3.是否在捕获阶段触发事件,需要布尔值,默认false
对象.removeEventListener(type,handler,false/true)
移除事件
参数和addEventListener的参数意思一样。