DOM
简介
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口
DOM树
窗口加载事件
// 为window绑定一个onload事件
window.onload = function() {
}
或者
window.addEventListener('load',function() {
});
// 该事件对应的响应函数将会在页面加载完成之后执行
// 这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了
window.onload是窗口(页面)加载事件,会在页面或图像加载完成后立即发生。通常用于 < body > 元素,在页面完全载入后(包括图片、css文件等等。)执行脚本代码。
<!-- 图片载入后立即弹出:"图片加载完成" -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
function loadImage(){
alert("图片加载完成");
}
</script>
</head>
<body>
<img src="logo.png" onload="loadImage()" width="336" height="36">
</body>
</html>
事件
// 事件三要素
// 点击一个按钮,弹出对话框
// 1.事件是由三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素
// 事件源 事件被触发的对象 谁 在这个案例里是按钮
var btn = document.getElementById('btn');
// 事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
// 事件处理程序 通过一个函数赋值的方式 完成
btn.onclick = function() {
alert('帅!');
}
执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
// 执行事件步骤
// 点击div 控制台输出 我被选中了
// 1.获取事件源
var div = document.querySelector('div');
// 2.绑定事件 注册事件1
// div.onclick
// 3.添加事件处理程序
div.onclick = function() {
console.log('我被选中了');
}
常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
获取元素
获取页面中的元素可以使用以下几种方式
- 根据ID获取
- 根据标签名获取
- 通过HTML5新增的方法获取
- 特殊元素获取
根据ID获取
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="btn">我是一个按钮</button>
<!-- 1.因为我们文档页面从上往下加载,所以先得有标签 所以我们script写到标签的下面 -->
<script type="text/javascript">
// 获取button对象
// 2.get 获得 element 元素 by 通过
// 3.参数id是大小写敏感的字符串
// 获取button对象
var btn = document.getElementById('btn');
// 4.返回的是一个元素对象
console.log(typeof btn); // object
// 5.console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法
console.dir(btn);
</script>
</body>
</html>
根据标签名获取
// getElementsByTagName()方法可以返回带有指定标签名的对象的集合
document.getElementsByTagName('标签名');
注意:
- 因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历
- 得到元素对象是动态的
还可以获取某个元素(父元素)内部所有指定标签名的子元素
element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(必须指明是哪一个元素对象),获取时不包括父元素自己
<body>
<ul>
<li>最带琴女36E</li>
<li>最带琴女37E</li>
<li>最带琴女38E</li>
<li>最带琴女39E</li>
<li>最带琴女40E</li>
</ul>
<ol>
<li>大大大</li>
<li>大大大</li>
<li>大大大</li>
<li>大大大</li>
<li>大大大</li>
</ol>
<script type="text/javascript">
// 获取所有的li(这里有10个)
// 1.返回的是 获取过来元素对象的集合 以伪数组的形式存储的
var lis = document.getElementsByTagName('li');
console.log(lis);
console.log(lis[0]);
// 2.我们想要依次打印里面的元素对象,可以采取遍历的方式
for (var i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
// 3.如果页面中只有一个li 返回的还是伪数组的形式
// 4.如果页面中没有这个元素 返回的是空的伪数组的形式
// 获取ol里面的li(这里有5个)
// 5.element.getElementsByTagName('标签名'); 父元素必须是指定的单个元素
var ol = document.getElementsByTagName('ol'); // [ol]
console.log(ol[0].getElementsByTagName('li'));
</script>
</body>
根据name属性获取
getElementsByName()
通过HTML5新增的方法获取
document.getElementsByClassName('类名'); // 根据类名返回元素对象集合
document.querySelector('选择器'); // 根据指定选择器返回第一个元素对象
document.querySelectorAll('选择器'); // 根据指定选择器返回
<body>
<div class="box">
<ul>
<li id="nav">首页</li>
<li>产品</li>
</ul>
</div>
<script type="text/javascript">
// 1.getElementsByClassName 根据类名获得某些元素集合
var boxs = document.getElementsByClassName('box');
console.log(boxs);
// 2.querySelector 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号 .box #nav
var firstBox = document.querySelector('.box');
console.log(firstBox);
var nav = document.querySelector('#nav');
console.log(nav);
var li = document.querySelector('li');
console.log(li);
// 3.querySelectorAll()返回指定选择器的所有元素对象集合
var allBox = document.querySelectorAll('.box');
console.log(allBox);
var lis = document.querySelectorAll('li');
console.log(lis);
</script>
</body>
获取特殊元素
获取body元素
document.body // 返回body元素对象
获取HTML元素
document.documentElement // 返回html元素对象
节点
Node—构成HTML文档最基本的单元
常用节点分为四类
- 文档节点:整个HTML文档
- 元素节点:HTML文档中的HTML标签
- 属性节点:元素的属性
- 文本节点:HTML标签中的文本内容
获取元素通常使用两种方式:
- 利用DOM提供的方法获取元素
document.getElementById()
document.getElementsByTagName()
document.querySelector 等
// 逻辑性不强、繁琐
-
利用节点层级关系获取元素
利用父子兄节点关系获取元素
逻辑性强,但是兼容性稍差
这两种方式都可以获取元素节点,我们后面都会使用,但是节点操作更简单
父子节点
node.parentNode
// 1. parenNode 属性可返回某节点的父节点,注意是最近的一个父节点
// 2. 如果指定的节点没有父节点则返回 null
<body>
<!-- 节点的优点 -->
<div class="box">
<span class="erweima">x</span>
</div>
<script type="text/javascript">
// 1.父节点 parentNode
var erweima = document.querySelector('.erweima');
// var box = document.querySelector('.box');
// 得到的是离元素最近的父级节点(亲爸爸),如果找不到父节点就返回null
console.log(erweima.parentNode); // box
</script>
</body>
子节点
parentNode.childNodes (标准)
// parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合
// 注意:返回值里面包含了所有子节点,包括元素节点,文本节点等
// 如果只想要获得里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
parentNode.children (非标准)
// parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(这个是重点)
// 虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
<body>
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<ol>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ol>
<div class="demo">
<div class="box">
<span class="erweima">x</span>
</div>
</div>
<script type="text/javascript">
// DOM 提供的方法(API)获取
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
// 1.子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等
console.log(ul.childNodes);// [text, li, text, li, text, li, text, li, text]
console.log(ul.childNodes[0].nodeType); // 3
console.log(ul.childNodes[1].nodeType); // 1
// 2.children 获取所有的子元素节点 也是我们实际开发常用的
console.log(ul.children); // [li, li, li, li]
</script>
</body>
第一个子元素和最后一个子元素
parentNode.firstChild
// firstChild 返回第一个节点,找不到则返回 null,同样,也是包含所有的节点
parentNode.lastChild
// lastChild 返回最后一个节点,找不到则返回 null,同样,也是包含所有的节点
// 注意:这两个方法有兼容性问题,IE9以上才支持
<body>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script type="text/javascript">
var ol = document.querySelector('ol');
// 1.firstChild 第一个子节点 不管是文本节点还是元素节点
console.log(ol.firstChild); // text
console.log(ol.lastChild); // text
// 2.firstElementChild 返回第一个子元素节点
console.log(ol.firstElementChild); // li1
console.log(ol.lastElementChild); // li4
// 3.实际开发的写法 既没有兼容性问题又返回第一个子元素
console.log(ol.children[0]); // li1
// 最后一个
console.log(ol.children[ol.children.length - 1]); // li4
</script>
</body>
兄弟节点
node.nextSibling
// nextSibling 返回当前元素的下一个兄弟节点,找不到则返回 null。同样,也是包含所有的节点
node.previousSibling
// perviousSibling 返回当前元素上一个兄弟节点,找不到则返回 null。同样,也是包含所有的节点
// 注意:下面的两个方法有兼容性问题,IE9以上才支持
node.nextElementSibling
// nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回 null
node.previousElementSibling
// previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回 null
<body>
<div>我是div</div>
<span>我是span</span>
<script type="text/javascript">
var div = document.querySelector('div');
// nextSibling 下一个兄弟节点 包含元素节点或者文本节点等
console.log(div.nextSibling); // #text
console.log(div.previousSibling); // #text
console.log(div.nextElementSibling); // <span>我是span</span>
console.log(div.previousElementSibling); // null
</script>
</body>
创建节点
document.createElement('tagName');
// 可用于创建一个元素节点对象,需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回
// 创建li元素节点
var li = document.createElement('li');
创建文本节点
document.createTexNode();
// 可用于创建一个文本节点对象
// 需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回
// 创建娑娜文本节点
document.createTextNode('娑娜');
添加节点
appendChild()
// 向一个父节点中添加一个新的子节点
// 用法:父节点.appendChild(子节点);
// 创建指定文本的li
var btn = document.createElement("BUTTON");
var t = ocument.createTextNode("CLICK ME");
// 把 CLICK ME 添加到按钮btn里
btn.appendChild(t);
insertBefore()
// 可以在指定的子节点前插入新的子节点
// 语法:父节点.indertBefore(新节点,旧节点);
// 1.创建节点元素节点
var li = document.createElement('li');
// 获取ul
var ul = document.querySelector('ul');
// 2.添加节点 node.appendChild(child) node 父级 child是子级 后面追加元素 类似于数组中的push
ul.appendChild(li);
// 3.添加节点 node.inserBefore(child,指定元素);
var lili = document.createElement('li');
ul.insertBefore(lili,ul.children[0]);
// 4.我们想要页面添加一个新的元素:1.创建元素 2.添加元素
替换节点
replaceChild()
// 可以使用指定的子节点替换已有的子节点
<!-- 语法:父节点.replaceChild(新节点,旧节点); -->
<body>
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul>
<p id="demo">单击按钮替换列表中的第一项。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction(){
var textnode=document.createTextNode("Water");
var item=document.getElementById("myList").childNodes[0];
item.replaceChild(textnode,item.childNodes[0]);
}
</script>
<p>首先创建一个文本节点。<br>然后替换第一个列表中的第一个子节点。</p>
<p><strong>注意:</strong>这个例子只将文本节点的文本节点“Coffee”替换为“Water”,而不是整个LI元素,这也是替换节点的一种备选。</p>
</body>
删除节点
removeChild()
// 可以删除一个子节点
// 语法:父节点.removeChild(子节点);
<body>
<button>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>光头强</li>
</ul>
<script type="text/javascript">
// 1.获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
// 2.删除元素 node.removeChild(child)
// ul.removeChild(ul.children[0]);
btn.onclick = function() {
if (ul.children.length == 0) {
// 数组长度为0时,按钮不可点击
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
复制节点
cloneNode()
// cloneNode() 方法返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点
// 注意:
// 1. 如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
// 2. 如果括号为true,则是深度拷贝,会复制节点本身以及里面所有的子节点
<body>
<ul id="myList1"><li>Coffee</li><li>Tea</li></ul>
<ul id="myList2"><li>Water</li><li>Milk</li></ul>
<p id="demo">单击按钮将项目从一个列表复制到另一个列表中</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction(){
var itm=document.getElementById("myList2").lastChild;
// 若里面为false,则文本Milk不会被复制,只有空的li
var cln=itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
</script>
</body>
操作元素
DOM操作可以改变网页的内容、结构、样式,我们可以利用DOM操作元素来改变元素里面的内容、属性等。
改变元素内容
element.innerText
// 从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉
element.innerHTML
// 起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
div