DOM简介
文档对象模型(_D_ocument _O_bject _M_odel),简称DOM,是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准接口。
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式。
- 文档:一个页面就是一个文档,DOM中使用document表示。
- 元素:页面中所有标签都是元素,DOM中使用element表示。
- 节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示。
DOM把以上内容都看做是对象
获取元素
DOM在我们实际开发中主要用来操作元素。
获取页面中的元素可以使用以下几种方式:
- 根据ID获取
- 根据标签名获取
- 通过HTML5新增的方法获取
- 特殊元素获取
根据ID获取
使用 getElementById()
方法可以获取带有ID的元素对象。
<div id="time">2020-2-2</div>
<script>
var timer = document.getElementById('time');
console.log(timer);
console.log(typeof timer);
console.dir(timer); //可以打印返回的元素对象,更好的查看里面的属性和方法
</script>
- get获得
element
元素 by通过 驼峰命名法 - 参数id是大小写敏感的字符串所以要加单引号
- 返回的是一个元素对象
根据标签名获取
使用 getElementByTagName()
方法可以获得所有标签名的对象的集合。
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var list = document.getElementsByTagName('li')
console.log(list);
console.log(list[1]);
//依次打印元素对象采用遍历的方式
for (var i = 0; i < list.length; i ) {
console.log(list[i]);
}
</script>
- 返回的是获取到元素对象的集合,以伪数组的形式存储的。
- 如果页面中只有一个标签,返回的还是伪数组的形式。
- 如果页面中没有这个元素,返回的是一个空的伪数组。
还可以获取某个元素(父元素)内部所有指定标签名的子元素。
代码语言:javascript复制 Element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(必须指明是哪一个元素),获取的时候不包括父元素自己。
代码语言:javascript复制 var ol = document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
H5新增获取元素方式
- 根据类名返回元素对象集合
document.getElementsByClassName('类名');
querySelector
返回指定选择器的第一个元素对象
document.querySelector('.类名');
document.querySelector('#ID名');
document.querySelector('标签名');
querySelectorAll()
返回指定选择器的所有元素对象集合
document.querySelectorAll('.类名');
document.querySelectorAll('#ID名');
document.querySelectorAll('标签名');
获取特殊元素(body,html)
- 获取body元素
var bodyEle = document.body;//返回body元素对象
console.log(bodyEle);
console.dir(bodyEle);
- 获取html元素
var htmlEle = document.documentElement;//返回html元素对象
console.log(htmlEle);
事件基础
JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为。
简单理解:触发---相应机制
网页中的每个元素都可以产生某些可以触发JavaScript的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。
事件三要素
事件由三部分组成:事件源、事件类型、事件处理程序。
- 事件源:事件被触发的对象,谁被点击---按钮
- 事件类型:如何触发,什么事件,比如鼠标点击(
onclick
)还是鼠标经过或者是键盘按下。 - 事件处理程序:通过一个函数赋值的方式完成。
案例:点击一个按钮,弹出对话框
代码语言:javascript复制 <button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function() {
alert('弹出信息')
}
</script>
执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
//1.获取事件源
var div = document.querySelector('div');
//2.绑定事件 注册事件--div.onclick
//3.添加事件处理程序
div.onclick = function() {
console.log('我被点击了');
}
常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
操作元素
JavaScript的DOM可以改变网页内容、结构和样式,我们可以利用DOM操作元素来改变元素里面的内容、属性等。注意以下都是属性。
改变元素内容
代码语言:javascript复制element.innerText
从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉。
代码语言:javascript复制element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行。
代码语言:javascript复制 <button>显示系统时间</button>
<div>某个时间</div>
<p>123</p>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function() {
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>
innerText
和 innerHTML
的区别
- innerText不识别html标签,非标准
- innerHTML识别html标签,W3C标准
- 这俩个属性是可读写的,可以获取元素里面的内容。
修改元素属性
代码语言:javascript复制 <button id="btn1">111</button>
<button id="btn2">222</button>
<img src="111.jpg" alt="" title="111">
<script>
//修改元素属性 src
//1.获取元素
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
var img = document.querySelector('img');
//注册事件,处理程序
btn2.onclick = function() {
img.src = '222.jpg';
img.title = '222';
}
btn1.onclick = function() {
img.src = '111.jpg';
img.title = '111';
}
</script>
JavaScript案例:分时显示不同图片,显示不同问候语
要求根据不同时间,页面显示不同图片,同时显示不同的问候语。如果上午时间打开页面,显示上午好,显示上午的图片。如果下...
修改表单属性
利用DOM可以操作如下表单元素的属性:
type
、value
、checked
、selected
、disabled
<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标签里面的内容
// 表单里面的值 文字内容是通过value来修改的
input.value = '被点击了';
//如果想要某个表单被禁用 不能再点击,disabled
//我们想要这个按钮button禁用
//btn.disabled = true;
this.disabled = true;
//this 指向的是事件函数的调用者btn
}
</script>
JavaScript案例:仿京东显示密码
点击按钮将密码框切换为文本框,并可以查看密码明文。核心思路:点击眼睛按钮,把密码框类型改为文本框就可以看见里面的密...
修改样式属性
我们可以通过JS修改元素的大小、颜色、位置等样式。
代码语言:javascript复制element.style //行内样式操作
element.className //类名样式操作
注意:
- JS里面的样式采取驼峰命名法,比如fontSize、backgroundColor
- JS修改style样式操作,产生的是行内样式,CSS权重比较高
使用element.style修改样式属性
如果样式比较少或者功能简单的情况下使用
代码语言:javascript复制 <style>
div {
width: 300px;
height: 300px;
background: red;
}
</style>
</head>
<body>
<div></div>
<script>
//1.获取元素
var div = document.querySelector('div');
//2.注册事件处理程序
div.onclick = function() {
this.style.backgroundColor = 'blue';
this.style.width = '250px';
this.style.height = '250px';
}
</script>
JavaScript案例:循环精灵图和显示隐藏文本框内容
循环精灵图利用for循环设置一组元素的精灵图背景找到精灵图图片排列的规律核心思路:利用for循环,修改精灵图片的背...
使用className修改样式属性
适合于样式较多或者功能复杂的情况。
代码语言:javascript复制 <style>
div {
width: 100px;
height: 100px;
background: red;
}
.change {
background-color: purple;
color: #fff;
font-size: 25px;
margin-top: 100px;
}
</style>
</head>
<body>
<div>文本</div>
<script>
//1.获取元素
var div = document.querySelector('div');
//2.注册事件处理程序
div.onclick = function() {
//让我们当前元素的类名改为了change
this.className = 'change';
}
</script>
</body>
- 如果样式修改比较多,可以采取操作类名方式更改元素样式
- class因为是个保留字,因此使用className来操作元素类名属性
- className会直接更改元素的类名,会覆盖原先的类名
注意:如果想要保留原先的类名,可以选择多类名选择器
代码语言:javascript复制 this.className = 'first change';
JavaScript案例:密码框格式提示错误信息
用户如果离开密码框。里面输入个数不是6~16,则提示错误信息,否则提示输入信息正确。首先判断的事件是表单失去焦点 ...
操作元素总结
排他思想
如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法:
- 所有元素全部清除样式(干掉其他人)
- 给当前元素设置样式(留下自己)
- 注意顺序不能颠倒,先干掉别人,再设置自己。
<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() {
//先把所有的按钮背景颜色去掉
for (var i = 0; i < btns.length; i ) {
btns[i].style.backgroundColor = '';
}
//然后才让当前的背景颜色为pink
this.style.backgroundColor = 'pink';
}
}
</script>
JavaScript案例:页面背景替换
页面背景替换效果演示点击查看操作效果案例分析练习给一组元素注册事件给四个图片利用循环注册事件点击那个图片,页面背景...
JavaScript案例:表格隔行变色效果及表单全选取消全选
表格隔行变色效果案例分析用到鼠标事件 鼠标经过 onmouseover 鼠标离开 onmouseout核心思路:鼠...
自定义属性的操作
获取属性值
element.属性
获取属性值element.getAttribute('属性')
get得到获取 attribute属性
<body>
<div id="demo"></div>
<script>
var div = document.getElementById('demo');
//1.element.属性 获取属性值
console.log(div.id); //demo
//2.element.getAttribute('属性') 获取属性值
console.log(div.getAttribute('id')); //deom
</script>
</body>
区别:
element.属性
获取的内置属性值(元素本身自带的属性)
element.getAttribute('属性')
主要获得自定义的属性(标准)我们自定义的属性
设置属性值
element.属性 = '值'
设置内置属性element.setAttribute('属性','值');
//1.element.属性='值'
div.id = 'test';
div.className = 'navs';
//2.element.setAttribute('属性','值') 主要针对自定义属性
div.setAttribute('index', 2);
div.setAttribute('class', 'footer');//class特殊 这里写的就是class 不是className
移除属性值
removeAttribute(属性)
移除属性值
div.removeAttribute('index');
JavaScript案例:tab栏切换
案例分析Tab栏切换有2个大的模块上面的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想)修改类...
H5自定义属性
自定义属性目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中。
自定义属性获取是通过 getAttribute('属性')
获取。
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
H5给我们新增了自定义属性
1.设置H5自定义属性
H5规定自定义属性data-开头做为属性名并且赋值
例:
或者使用JS设置:element.setAttribute('data-index',2)
2.获取H5自定义属性
- 兼容性获取
element.getAttribute('data-index');
- H5新增的方法:
element.dataset.index
或者element.dataset['index']
其ie11才支持
dataset
是一个集合,里面存放了所有以 data-
开头的自定义属性,它只能获取 data-
开头的。
如果自定义属性里面有多个 -
连接的单词,我们获取的时候采用驼峰命名法。
节点操作
获取元素通常使用两张方式
1.利用DOM提供的方法获取元素
- document.getElementById()
- document.getElementByTagName()
- document.querySelector()
- 逻辑性不强、繁琐
2.利用节点层级关系获取元素
- 利用父子兄节点获取元素
- 逻辑性强,但是兼容性稍差
这两种方式都可以获取元素节点,我但是节点操作更简单。
概述:网页中所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。
HTML DOM树中的所有节点均可以通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
- 元素节点 nodeType 为1
- 属性节点 nodeType为2
- 文本节点 nodeType为3(文本节点包含文字、空格、换行等)
在实际开发中,节点操作主要操作的是元素节点。
节点层级
利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系
1.父级节点
代码语言:javascript复制node.parentNode
- parentNode属性可返回某节点的父节点,注意是最近的一个父节点
- 如果指定的节点没有父节点则返回null
<div class="demo">
<div class="box">
<span class="son">子</span>
</div>
</div>
<script>
var son = document.querySelector('.son')
console.log(son.parentNode);//box
</script>
2.子节点
代码语言:javascript复制parentNode.childNodes(标准)
- 返回包含指定节点的子节点的集合,该集合为即使更新的集合。
- childNode获得的是所有类型的子节点,包含元素节点、文本节点等,如果想要获得里面的元素节点,则需要专门处理,所以我们不提倡使用childNodes。
parentNode.children(非标准)
获取所有的子元素节点,也是我们实际开发常用的。
代码语言:javascript复制 <ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<script>
var uls = document.querySelector('ul');
console.log(uls.children);
</script>
第一个和最后一个子元素:
代码语言:javascript复制parentNode.firstChild
返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。
代码语言:javascript复制parentNode.lastChild
返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
代码语言:javascript复制parentNode.firstElementChild
返回第一个子元素节点,找不到则返回null。IE9以上才支持。
代码语言:javascript复制parentNode.lastElementChild
返回最后一个子元素节点,找不到则返回null。IE9以上才支持。
实际开发中的解决方案,既没有兼容性问题又返回第一个子元素或最后一个元素。
代码语言:javascript复制 console.log(uls.children[0]);
console.log(uls.children[uls.children.length - 1]);
JavaScript案例:下拉菜单
案例分析导航栏里面的li都要有鼠标经过效果,所以需要循环注册鼠标事件核心原理:当鼠标经过li里面的第二个孩子ul显...
兄弟节点
代码语言:javascript复制node.nextSibling
返回当前元素的下一个兄弟节点,找不到则返回null,同样,也是包含所有的节点。
代码语言:javascript复制node.previousSibling
返回当前元素的上一个兄弟节点,找不到则返回null,同样,也是包含所有的节点。
代码语言:javascript复制node.nextElementsiSbling
返回当前元素下一个兄弟元素节点,找不到则返回null。
代码语言:javascript复制node.previousElementsiSbling
返回当前元素上一个兄弟元素节点,找不到则返回null。
代码语言:javascript复制<body>
<div class="box">div</div>
<span class="son">span</span>
<script>
var div = document.querySelector('div');
//包含文本节点、元素节点
console.log(div.nextSibling);
console.log(div.previousSibling);
//仅获取元素节点
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
</script>
</body>
在后两种方式中可能会面临兼容性的问题,我们可以自己封装一个兼容性的函数来解决。
代码语言:javascript复制 function getNextElementSibling(element) {
var el = element;
while (el = el.nextSibling) {
if (el.nodeType == 1) {
return el;
}
}
return null;
}
创建添加节点
代码语言:javascript复制 document.createElement('tagName');
此方法创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为 动态创建元素节点
。
node.appenChild(child)
将一个节点添加到指定夫节点的子节点列表末尾。类似于css里面的after伪元素。
代码语言:javascript复制node.insertBefore(child,指定元素)
将一个节点添加到父节点的指定子节点前面,类似于css里面的before伪元素。
代码语言:javascript复制 <ul>
<li>123</li>
</ul>
<script>
//1.创建节点元素节点
var li = document.createElement('li');
//2.添加节点 node.appendChild(child) node父级,child子级,后面追加元素,类似于数组中的push
var ul = document.querySelector('ul');
ul.appendChild(li)
//3.添加指定元素节点
var lil = document.createElement('li');
ul.insertBefore(lil, ul.children[0]);
</script>
JavaScript案例:简单留言发布
案例分析核心思路:点击按钮之后,就动态创建一个li,添加到ul里面创建li的同时,把文本域里面的值通过li.inn...
删除节点
代码语言:javascript复制node.removeChild(child)
从DOM中删除一个子节点,返回删除的节点。
案例:点击按钮删除
代码语言:javascript复制<body>
<button>删除</button>
<ul>
<li>胸大</li>
<li>屁股大</li>
<li>腰细</li>
</ul>
<script>
//获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button')
//删除元素
// ul.removeChild(ul.children[0])
//点击按钮依次删除
btn.onclick = function () {
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
复制节点
代码语言:javascript复制node.cloneNode()
返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点
代码语言:javascript复制<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
//浅拷贝
var lili = ul.children[0].cloneNode();
//深拷贝
var lili = ul.children[0].cloneNode(true);
ul.appendChild(lili);
</script>
</body>
- 如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
- 如果括号参数为true,则是深拷贝,会复制节点本身以及里面所有的子节点。
JavaScript案例:动态生成表格
创建数据因为里面的数据都是动态的,我们需要js动态生成,所以需要准备好模拟数据,采用对象形式存储。 <...