1.DOM简介
1.1 什么是DOM
DOM(Document Object Model):文档对象模型,是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口。W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。
1.2DOM树
-
文档:一个界面就是一个文档,DOM中是用Document表示
-
元素:页面中所有的标签都是元素,DOM中使用element表示
-
节点:网页中所有内容都是节点(标签,属性,文本,注释),DOM中使用node表示
DOM把以上内容都看作是对象
2. 获取元素
2.1 根据ID获取
使用getElementById()
语法
var element = document.getElementById(id);
参数
-
element是一个Element对象,如果当前文档拥有特定ID的元素不存在,则返回NULL
-
id是大小写敏感的字符串,代表所要查找的元素的唯一ID
返回值
返回一个匹配到ID的DOM Element 对象,若在当前Document没有找到,则返回NULL
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="p2">
<p>宋亚轩会一直是宋亚轩</p>
</div>
<script>
var p2 = document.getElementById('p2');
//1.文档页面从上到下加载,所以得先有标签 所以script写在标签的下面
//2.get 获得element 元素 by 通过 驼峰命名法
//3.参数 id是带小写敏感的字符串
console.log(p2);
console.log(typeof p2);
//4.返回的是一个元素对象
console.dir(p2)
//5.console.dir打印我们返回的元素对象 更好的查看里面的属性和方法
</script>
</body>
</html>
2.2根据标签名获取
getElementsByTagName()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var p1 = document.getElementsByClassName('p1');
var p2 = document.getElementById('p2')
var d1 = document.getElementById("div1"); // object HTMLDivElement
</script>
</head>
<body>
<ul>
<li>永远喜欢宋亚轩</li>
<li>永远喜欢宋亚轩</li>
<li>永远喜欢宋亚轩</li>
<li>永远喜欢宋亚轩</li>
<li>永远喜欢宋亚轩</li>
</ul>
<ol id="ol">
<li>少年无畏</li>
<li>少年无畏</li>
<li>少年无畏</li>
<li>少年无畏</li>
</ol>
<script>
//返回的是获取过来元素对象的集合 以伪数组的形式储存的
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.如果页面中没有li,返回空数组
//5.element.getElementByTagName('标签名');父元素必须是指定的单个元素
var ol = document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
</script>
</body>
</html>
2.3 通过HTML5新增的方法获取
document.getElementByClassName
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var p1 = document.getElementsByClassName('p1');
var p2 = document.getElementById('p2')
var d1 = document.getElementById("div1"); // object HTMLDivElement
</script>
</head>
<body>
<div class="box">盒子</div>
<div class="box">盒子</div>
<div class="nav">
<ul>
<li>首页</li>
<li>产品</li>
</ul>
</div>
<script>
//1.getElementByClassName 根据类名获得某些元素集合
var boxs = document.getElementsByClassName('box');
console.log(boxs);
//2.querySelecter 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号
var firstBox = document.querySelector('.box');
console.log(firstBox);
var nav = document.querySelector('#nav0');
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>
</html>
2.4 获取特殊元素
-
获取body元素
document.body
-
获取html元素
document.documentElement
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
//1.获取body元素
var bodyELe = document.body;
console.log(bodyELe);
console.dir(bodyELe);
//2.获取html元素
//var htmlEle = document.html;
var htmlEle = document.documentElement;
console.log(htmlEle);
</script>
</body>
</html>
3. 事件基础
3.1 事件概述
JavaScript使我们能力创建动态页面,而事件是可以被JavaScript检测到的行为。
简单理解:触发---响应机制
网页的每个元素都可以产生某些可以触发JavaScript的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。
3.2 事件三要素
事件源 事件类型 事件处理程序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn">宋亚轩</button>
<script>
//点击一个按钮,弹出对话框
//1.事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素
//(1)事件源 事件被触发的对象 谁 按钮
var btn = document.getElementById('btn');
//(2)事件类型 如何触发 什么事件 比如鼠标点击(onclick)还是鼠标经过 还是键盘放下
//(3)事件处理程序 通过一个函数赋值的方式完成
btn.onclick = function () {
alert('最帅');
}
</script>
</body>
</html>
3.3执行事件的步骤
-
获取事件源
-
注册事件(绑定事件)
-
添加事件处理程序(采取函数赋值形式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>123</div>
<script>
//执行事件步骤
//点击div 控制台输出 我被选中了
//1.获取事件源
var div = document.querySelector('div');
//2.绑定事件,注册事件
//div.onclick;
//3.添加事件处理程序
div.onclick = function () {
console.log('我被选中了');
}
</script>
</body>
</html>
4.操作元素
JavaScript的DOM操作可以改变网页内容,结构和样式,我们可以利用DOM操作元素来改变元素里面的内容,属性等
4.1 改变元素的内容
element.innnerText
从起始位置到终止位置的内容,但它除去html标签,同时空格和换行也会去掉
element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
例:innerText
<body>
<button>显示当前系统的时间</button>
<div>某个时间</div>
<p>123</p>
<script>
//当我们点击了按钮,div里面的文字会发生变化
//1.获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div');
//2.注册事件
btn.onclick = function () {
// div.innerText = '2023-4-21';
div.innerText = getDate();
}
function getDate() {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
var day = date.getDay();
return '今天是:' + year + '年' + month + '月' + dates + '日' + arr[day];
}
//我们元素可以不用添加事件
var p = document.querySelector('p');
p.innerText = getDate();
</script>
</body>
<body>
<div></div>
<p>
我是文字
<span>123</span>
</p>
<script>
//innerText 和innerHTML的区别
//1.innerText vu识别html标签 非标准 去除空格和换行
var div = document.querySelector('div');
// div.innerText = '<strong>今天是:</strong> 2019';//不识别strong标签
//2. innerHTML 识别html标签
div.innerHTML = '<strong>今天是:</strong> 2019';
//这两个属性是可读写的 可以获取元素里面的内容
var p = document.querySelector('p');
// console.log(p.innerText);
console.log(p.innerHTML);
</script>
</body>
4.2 常用元素的属性操作
-
innerText,innerHTML改变元素的内容
-
src,href
-
id,alt,title
<body>
<button id="syx">宋亚轩</button>
<button id="mjq">马嘉祺</button>
<button>丁程鑫</button>
<button>贺峻霖</button>
<button>严浩翔</button>
<button>张真源</button>
<button>刘耀文</button>
<img src="song.webp" title="宋亚轩">
<script>
//修改元素属性 src
//1. 获取元素
var syx = document.getElementById('syx');
var mjq = document.getElementById('mjq');
var dcx = document.getElementById('dcx');
var img = document.querySelector('img');
//2.注册事件 处理程序
syx.onclick = function () {
img.src = 'song.webp';
img.title = '宋亚轩';
}
mjq.onclick = function () {
img.src = 'ma.webp';
img.title = '马嘉祺';
}
</script>
</body>
未点击前
点击后
4.3 表单元素的属性操作
利用DOM可以操作如下表单元素的属性
type,value,checked,selected,disabled
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>按钮</button>
<input type="text" value="输入内容">
<script>
//1.获取元素
var btn = document.querySelector('button');
var input = document.querySelector('input');
//2.注册事件
btn.onclick = function () {
//input.innerHTML = '点击了';这个是普通盒子,如div标签里面的内容
input.value = '被点击了';
//如果想要某个表单被禁用,不能再点击disabled 我们想要这个按钮button禁用
//btn.disabled = true;
this.disabled = true;
//ths指向的是事件函数的调用者
}
</script>
</body>
</html>
4.4 样式属性操作
我们可以通过JS修改元素的大小,颜色,位置等样式
element.style 行内样式操作 element.className 类名样式操作
第一种:行内样式操作
如果样式比较少 或者 功能简单的情况下使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
//1.获取元素
var div = document.querySelector('div');
//2.注册事件 处理程序
div.onclick = function () {
//div里面的属性采取驼峰命名
this.style.backgroundColor = 'purple';
this.style.width = '250px';
}
</script>
</body>
</html>
注意:
-
JS里面的样式采取驼峰命名法 比如backgroundColor
-
JS修改style样式操作,产生的是行内样式,CSS权重比较高
第二种:类名样式操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
.change {
background-color: purple;
color: #FFF;
font-size: 25px;
margin-top: 100px;
}
</style>
</head>
<body>
<div class="first">文本</div>
<script>
//1.获取元素
var div = document.querySelector('div');
//2.注册事件 处理程序
div.onclick = function () {
//div里面的属性采取驼峰命名
// this.style.backgroundColor = 'purple';
// this.style.width = '250px';
// this.style.color = '#FFF';
// this.style.fontsize = '25px';
// this.style.marginTop = '100px';
//让我们当前的类名改为change
//2.我们可以通过修改元素className更改元素的样式 适合于样式较多或者功能复杂的情况
//3.如果想要保留原先的类名,可以这么做
//this.className = 'change';
this.className = 'first change';
}
</script>
</body>
</html>
注意:
-
如果样式修改过多,可以采取操作雷鸣的方式更改元素样式
-
class因为是个保留字,因此使用className来操作元素类名属性
-
className 会直接更改元素的类名,会覆盖原先的类名
4.5 排他思想
如果有同一组元素,我们想要某一个元素实现某种样式,需要用到的循环的派他思想的算法:
-
所有元素全部清除样式(干掉其他人)
-
给当前元素设定样式(留下我自己)
-
之一顺序不能颠倒,首先干掉其他人,再设置自己
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
//1.获取所有元素按钮
var btns = document.getElementsByTagName('button');
//btns得到的是伪数组 里面的每一个元素btns[i]
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
// console.log(11);
//(1)我们先把所有的按钮背景颜色都去掉
for (var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = '';
}
//(2)然后才能让当前的元素为pink
this.style.backgroundColor = 'pink';
}
}
</script>
</body>
4.6 自定义属性的操作
-
获取属性值
-
element.属性 获取属性值
-
element.getAttribute('属性');
区别:
-
element.属性 获取内置属性值(元素本身带有的属性)
-
element.getAttribute('属性');主要获取自定义的属性(标准)
<body>
<div id="demo" index="1"></div>
<script>
var div = document.querySelector('div');
//1.获取元素的属性值
//(1)element.属性
console.log(div.id);
//(2)element.getAttribute('属性') get得到获取 attribute 属性的意思 我们自己定义的属性
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
</script>
</body>
-
设置属性值
-
element.属性值 = '值' 设置内置属性值
-
element.setAttribute('属性','值');
//2.s设置元素属性值 //(1)element.属性= '值'; div.id = 'test'; div.className = 'navs'; //(2)element.setAttibute('属性','值');主要针对自定义属性 div.setAttibute('index', 2); div.setAttribute('class','footer');
-
-
移除属性
-
element.removeAttribute('属性');
//3.移除属性 div.removeAttribute('class');
-
4.7H5自定义属性
自定义属性的目的:为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中
-
设置H5自定义属性
H5规定自定义属性data-开有作为属性名并赋值
比如:<div data-index="1"></div>
或者使用JS设置
element.setAttibute('data-index',2)
<body> <div getTime="20" data-index="1"></div> <script> var div = document.querySelector('div'); console.log(div.getTime); console.log(div.getAttribute('getTime')); div.setAttribute('data-time', 20); </script> </body>
-
获取H5自定义属性
-
兼容性获取
element.getAttribute('data-index'); (常用)
-
H5新增element.dataset.index或者element.dataset['index']
-
<body>
<div getTime="20" data-index="1" data-list-name="andy"></div>
<script>
var div = document.querySelector('div');
console.log(div.getTime);
console.log(div.getAttribute('getTime'));
div.setAttribute('data-time', 20);
console.log(div.getAttribute('getTime'));
//H5新增的获取自定义属性的方法 它只能获取data-开头的
//dataset是一个集合,里面存放了所有以data-开头的自定义属性
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
//注意 如果自定义属性里面有多个-链接的单词,我们获取时采用驼峰命名
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
</body>
总结:
5. 节点操作
5.1 为什么学节点操作
获取元素通常使用的两种方式:
-
利用DOM提供的方法获取元素
-
document.getElementById()
-
document.getElementsByTagName()
-
document.querySelector
-
逻辑性不强,繁琐
-
-
利用节点层级关系获取元素
-
利用父子兄弟节点关系获取元素
-
逻辑性强,但兼容性差
-
5.2节点概述
网页中的所有内容都是节点(标签,属性,文本,注释等),在DOM中,节点使用node表示
HTML DOM树中的所有节点均可以通过JavaScript进行访问,所有HTML元素(节点)均可以被修改,也可以被创建或删除
一般的,节点至少拥有nodeType(节点类型),nodeName(节点名称)和nodeValue(节点值)这三个基本属性
-
元素节点 nodeType为1
-
属性节点 nodeType为2
-
文本节点 nodeType为3(文本节点包含文字,空格,换行)
我们在实际开发中,节点操作主要操作的是元素节点
5.3 节点层级
-
父节点
node.parentNode
注意:
-
parentNode属性返回某节点的父节点,注意是最近的一个父节点
-
如果指定的节点没有父节点则返回null
<body>
<!-- Jiediande优点 -->
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<div>
<div class="box">
<span class="erweima">x</span>
</div>
</div>
<script>
//1.父节点 parentNode
var erweima = document.querySelector('.erweima');
// var box = document.querySelector('.box');
//得到的是锂元素最近的父级节点(亲爸爸)若果找不到父节点,返回为NULL
console.log(erweima.parentNode);
</script>
</body>
-
子节点
parentNode.childNodes(标准)
<body>
<ul>
<li>宋亚轩</li>
<li>宋亚轩</li>
<li>宋亚轩</li>
<li>宋亚轩</li>
</ul>
<ol>
<li>时代少年团</li>
<li>时代少年团</li>
<li>时代少年团</li>
<li>时代少年团</li>
<li>时代少年团</li>
</ol>
<script>
<!-- // DOM提供的方法(API)获取 -->
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
//1.子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等
console.log(ul.childNodes);
</script>
</body>
注意:返回值里面包含了所有的子节点,包括元素节点,文本节点
如果只想要获得里面的元素节点,则需要专门处理,我们一般不提倡使用childNodes
方法1:
var ul = document.querySelector('ul');
for(var i=0;i<ul.childNodes.length;i++){
if(ul.childNodes[i].nodeType==1){
//ul.childNodes[i]是元素节点
console.log(ul.childNodes[i]);
}
}
方法2:
parentNode.children(非标准)
parentNode.children是一个制度属性,返回所有的子元素节点,他只返回元素节点,其余节点不返回
parentNode.firstChild
返回第一个子节点,找不到则返回NULL
parentNode.lastChild
lastChild返回最后一个子节点,找不到则返回NULL
另外的方法:
parentNode.firstElementChild
parentNode.lastElementChild
则返回元素节点,但有兼容性问题
解决方案:
console.log(ol.children[0]);
console.log(ol.children[ol.chidren.length-1]);
-
兄弟节点
下一个节点
node.nextBibling
上一个节点
node.previousBibling
返回元素节点:(兼容性问题)
node.nextElementSibling
node.previousElementSibling
解决方案:自己封装一个兼容性函数
function getNextElementSiblig(element){
var el = element;
while(el = el.nextSibling){
if(el.nodeType==1){
return el;
}
}
return null;
}
5.4 创建节点 添加节点
创建节点
document.createElement('tagName')
document.createElement()方法创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们的需求动态生成的
添加节点
node.appendChild(child)
node.appendChild()方法将一个节点添加到指定父节点列表的末尾,类似与CSS里面的after的伪元素
node.insertBefore(child,指定元素)
node.insertBefore()方法将一个节点添加到父节点的指定子节点的前面
5.5 删除节点
node.removeChild(child)
node.removeChild(child)方法从DOM中删除一个子节点,返回删除的节点
5.6 复制节点
node.cloneNode()
node.cloneNode(true)
注意:
-
如果括号参数为空或者为false,则是浅拷贝,则值克隆节点本身,不克隆里面的子节点
-
如果括号参数为true,则是深度拷贝,会复制节点本身及里面所有的子节点
5.7 三种动态创建元素的区别
-
document.write()
-
innerHTML
-
document.createElement()
区别:
-
document.write是直接将内容写入页面的内容流,但是文档流执行完毕,将会导致页面全部重绘
-
innerHTML 是将内容写入某个DOM节点,不会导致页面重绘
-
innerHTML创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
-
createElement()创建多个元素效率稍低一点点,但是结构很清晰
6. DOM重点核心
6.1 创建
-
document.write
-
innerHTML
-
createElement
6.2 增
-
appendChild
-
insertBefore
6.3 删
-
removeChild
6.4 改
-
修改元素属性:src,href,title
-
修改普通元素内容:innerHTML,innerText
-
修改表单元素:value,type,disabled
-
修改元素样式:style,className
6.5 查
-
DOM提供的API方法:getElementById,getElementByTagName
-
H5提供的新方法:querySelector,querySelectorAll提倡
-
利用节点操作获取元素:父(parent Node),子(children),兄(previousElementSibling,nextElementSibling)提倡
6.6 属性操作
主要针对自定义属性
-
setAttribute:设置DOM的属性值
-
getAttribute:得到DOM的属性值
-
removeAttribute移除属性
6.7 事件操作