六、前端开发语言体系-JavaScript DOM
JavaScript DOM
DOM简介
所谓DOM,全称 Docuemnt Object Model 文档对象模型。
在文档中一切皆对象,比如html,body,div,p等等都看做对象。DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让js操作html元素而制定的一个规范。
解析过程:HTML加载完成,渲染引擎会在内存中把html文档,生成一个DOM树,getElementById是获取DOM上的元素节点。然后操作的时候修改的是该元素的属性。
DOM方法
DOM 方法是你能够(在 HTML 元素上)执行的动作,DOM 属性是您能够设置或改变的 HTML 元素的值。
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "Hello World!";
</script>
</body>
</html>
//在这个例子中,getElementById 是方法,使用 id="demo" 来查找元素
//而 innerHTML 是属性,可用于获取或替换 HTML 元素的内容。
- 查找 HTML 元素
方法 | 描述 |
---|---|
document.getElementById(id) | 通过元素 id 来查找元素 |
document.getElementsByTagName(name) | 通过标签名来查找元素 |
document.getElementsByClassName(name) | 通过类名来查找元素 |
- 改变 HTML 元素
方法 | 描述 |
---|---|
element.innerHTML = new html content | 改变元素的 inner HTML |
element.attribute = new value | 改变 HTML 元素的属性值 |
element.setAttribute(attribute, value) | 改变 HTML 元素的属性值 |
element.style.property = new style | 改变 HTML 元素的样式 |
- 添加和删除元素
方法 | 描述 |
---|---|
document.createElement(element) | 创建 HTML 元素 |
document.removeChild(element) | 删除 HTML 元素 |
document.appendChild(element) | 添加 HTML 元素 |
document.replaceChild(element) | 替换 HTML 元素 |
document.write(text) | 写入 HTML 输出流 |
DOM事件
JS是事件驱动为核心的一门语言,事件三要素有:
- 事件源:引起后续事件的html标签
- 事件:js已经定义好了,如onclick
- 事件驱动程序:对样式和html的操作。也就是DOM
代码书写步骤如下:
- 获取事件源:document.getElementById(“box”);
- 绑定事件:事件源box. 事件onclick和function( ){ 事件驱动程序 }
- 书写事件驱动程序:关于DOM的操作
常用事件有:
事件名 | 描述 |
---|---|
onclick | 鼠标单击 |
ondblclick | 鼠标双击 |
onkeyup | 按下并释放键盘上的一个键时触发 |
onchange | 文本内容或下拉菜单中的选项发生改变 |
onfocus | 获得焦点,表示文本框等获得鼠标光标 |
onblur | 失去焦点,表示文本框等失去鼠标光标 |
onmouseover | 鼠标悬停,即鼠标停留在图片等的上方 |
onmouseout | 鼠标移出,即鼠标离开图片等所在的区域 |
onload | 网页文档加载事件 |
onunload | 关闭网页时 |
onsubmit | 表单提交事件 |
onreset | 重置表单时 |
绑定事件的方式:
- 直接绑定匿名函数
//绑定事件的第一种方式
var oDiv = document.getElementById("box");
oDiv.onclick = function(){
alert("我是弹出的内容");
};
- 先单独定义函数,再绑定
//绑定事件的第二种方式,分为行外绑定和行内绑定
//行外绑定
var oDiv = document.getElementById("box");
oDiv.onclick = fn; //注意,这里是fn,不是fn()
//单独定义函数
function fn(){
alert("我是弹出的内容")
}
//行内绑定
<div id="box" onclick="fn()"></div> //这里是fn()
<script type="text/javascript">
function fn() {
alert("我是弹出的内容");
}
</script>
window.onload( )函数调用,是当页面加载完毕(文档和图片的时候)时,文档先加载,图片资源后加载。
JS的加载是和html同步加载的。因此,如果使用元素再定义元素之前,容易报错,这个时候,onload事件就能派上用场了,我们可以把使用元素的代码凡在onload里面,就能保证这段代码是最后执行的。
<script type="text/javascript">
window.onload = function () {
console.log("alex"); //等页面加载完毕时,打印字符串
}
</script>
window.onload()方法存在的问题:
- 图片加载完成才调用onload方法,如果现在用户访问JD商城页面,如果JD商城中的脚本文件在window.onload()方法调用,如果此时用户网速卡了,然后图片资源加载失败了,此时用户是做不了任何操作的,所以winodw.onload()方法有很大问题。
- window.onload()方法如果脚本中书写两个这样的方法,那么会有事件覆盖现象。
DOM事件监听器
在 HTML DOM 中有两种事件传播的方法:冒泡和捕获。
事件传播是一种定义当发生事件时元素次序的方法。假如< div > 元素内有一个< p >,然后用户点击了这个< p >元素,应该首先处理哪个元素“click”事件?
- 在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的。首先处理< p >元素的点击事件,然后是< div >元素的点击事件。
- 在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的。首先处理< div >元素的点击事件,然后是< p >元素的点击事件。
为了能够兼容更多的浏览器,建议多使用冒泡流。
DOM事件监听有两个方法:
- addEventListener( ) 方法
- removeEventListener( ) 方法
addEventListener( ) 方法为指定元素指定事件处理程序,该方法为元素附加事件处理程序而不会覆盖已有的事件处理程序,我们能够向一个元素添加多个事件处理程序。
addEventListener( ) 方法的语法为:
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型(比如 "click" 或 "mousedown")。
第二个参数是当事件发生时我们需要调用的函数。
第三个参数是布尔值,指定使用事件冒泡还是事件捕获。此参数是可选的。
注意:请勿对事件使用 "on" 前缀;请使用 "click" 代替 "onclick"。
一个向相同元素添加不同类型事件的例子:
element.addEventListener("mouseover", myFunction);
element.addEventListener("click", mySecondFunction);
function myFunction() {
alert ("Hello World!");
}
function mySecondFunction() {
alert ("This is JavaScript!");
}
addEventListener( ) 允许您将事件监听器添加到任何 HTML DOM 对象上,比如 HTML 元素、HTML 对象、window 对象或其他支持事件的对象。
添加当用户调整窗口大小时触发的事件监听器:
window.addEventListener("resize", function(){
document.getElementById("demo").innerHTML = sometext;
});
removeEventListener( ) 方法会删除已通过 addEventListener() 方法附加的事件处理程序。
removeEventListener( ) 方法的语法为:
element.removeEventListener(event, function);
第一个参数是事件的类型(比如 "click" 或 "mousedown")。
第二个参数是当事件发生时我们需要调用的函数。
实例:
element.removeEventListener("mousemove", myFunction);
IE 8、Opera 6.0 及其更早版本不支持 addEventListener( ) 和 removeEventListener( ) 方法。跨浏览器解决方案为:
var x = document.getElementById("myBtn");
if (x.addEventListener) { // 针对主流浏览器,除了 IE 8 及更正版本
x.addEventListener("click", myFunction);
} else if (x.attachEvent) { // 针对 IE 8 及更早版本
x.attachEvent("onclick", myFunction);
}
DOM样式和交互
HTML DOM 允许 JavaScript 更改 HTML 元素的样式。
- 样式属性的操作,就是对style 标签中的属性进行操作,并且通过js控制盒模型的属性(width,height等),控制盒子的显示隐藏(display:none|block),控制盒子的颜色切换(background:red|green)等。
<div id='box'></div>
<script>
window.onload = function(){
//1.获取事件源(事件对象,在文档中一切的标签都是对象)
var oDiv = docuement.getElementById('box');
//2.绑定事件
oDiv.onclick = function(){
//3.事件驱动程序 ps:记得 所有的style中使用的像margin-left 在js操作时都是用marginLeft属性进行赋值
oDiv.style.backgroundColor = 'yellow';
}
};
</script>
- 值的操作,就是标签中间的文本内容的设置和获取。
- 双闭合标签:innerText 或者 innerHTML
- 单闭合标签:除了img标签,就剩input了,使用value进行赋值
<div id='box'></div>
<input type='text' value = 'alex' id='user'>
<script>
window.onload = function(){
//1.获取事件源(事件对象,在文档中一切的标签都是对象)
var oDiv = docuement.getElementById('box');
var oInput = docuement.getElementById('user');
//2.绑定事件
oDiv.onclick = function(){
//3.事件驱动程序
oDiv.innerText = 'alex';//仅仅设置文本内容
oDiv.innerHTML = '<h1>alex</h1>';//将标签和文本内容一起解析
};
//2.绑定事件
oInput.onclick = function(){
//3.事件驱动程序 只有有value属性的 才能使用value赋值和设置值
oInput.value = 'wusir';
}
};
</script>
- 标签属性操作,就是对标签中属性的操作。比如像每个标签中id,class,title,img。以及标签中的src属性和alt属性、a标签的href属性、input标签中的name、type属性等等。
<script>
//需求:鼠标放到img上,更换为另一张图片,也就是修改路径(src的值)。
window.onload = function () {
//1.获取事件源
var oImg = document.getElementById("box");
//2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件)
oImg.onmouseover = function () {
//3.书写事件驱动程序(修改src)
img.src = "image/jd2.png";
// this.src = "image/jd2.png";
}
//2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件)
oImg.onmouseout = function () {
//3.书写事件驱动程序(修改src)
img.src = "image/jd1.png";
}
}
</script>
我们使用函数对节点进行操作。
- 创建节点
- 语法:新的标签(元素节点) = document.createElement(“标签名”);
<script type="text/javascript">
var a1 = document.createElement("li"); //创建一个li标签
var a2 = document.createElement("adbc"); //创建一个不存在的标签
console.log(a1);
console.log(a2);
console.log(typeof a1);
console.log(typeof a2);
</script>
- 插入节点
- 方式1:父亲点的最后插入一个新的子节点。
- 方式1语法:父节点.appendChild(新的子节点);
- 方式2:在参考节点前插入一个新的节点。
- 方式2语法:父亲点.insertBefore(作为参考的子节点)
- 删除节点
- 语法:父节点.removeChild(子节点);
DOM相关案例
简易留言板:
我们在文本框中输入内容
- 点击留言按钮,会添加到当前页面中。
- 点击统计按钮,会统计当前页面中有多少条留言
- 点击留言后面删除按钮(红叉),会删除当前留言
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>留言板</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
margin-left: 30%;
margin-top: 2%;
}
h1{
margin-left: 60px;
}
#msg{
width: 300px;
height: 120px;
}
#btn{
width: 40px;
height: 25px;
}
.close{
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
cursor: pointer;
background-color: rgba(0,0,0,.1);
margin-left: 20px;
background-color: red;
}
</style>
</head>
<body>
<h1>简易留言板</h1>
<textarea id="msg"></textarea>
<input type="button" id="btn" value="留言"/>
<button id="btn" onclick="sum()">统计</button>
<div id="box">
<!--<ul>
</ul>-->
</div>
</body>
<script type="text/javascript">
// 0 将ul标签添加到div#box标签中
var oUl = document.createElement('ul');
var oBox = document.getElementById('box');
oBox.appendChild(oUl);
var oBtn = document.getElementById('btn');
var oMsg = document.getElementById('msg')
// 控制留言的总数量
var count = 0;
oBtn.onclick = function(){
// 点击留言按钮事件操作
// 1.创建li标签
var oLi = document.createElement('li');
//2.设置内容
oLi.innerHTML = oMsg.value + "<span class='close'>X</span>"
// 3.如果想在插入的第一个li获取的前面继续添加li标签
//3.1获取li标签
var olis = document.getElementsByTagName('li');
//3.2 如果是第一次添加的li标签,则直接添加到ul的后面
if(olis.length == 0){
oUl.appendChild(oLi);
count++;
}else{
// 3.3 如果不是第一次添加的li标签,则插入到第一个li标签的前面
oUl.insertBefore(oLi,olis[0]);
count++;
}
// 4.添加完成之后 清空textarea的值
oMsg.value = '';
// 5.点击X的时候删除当前的一条数据
//5.1先获取所有的X
var oSpans = document.getElementsByTagName('span');
// 5.2for循环 对所有的X添加点击事件
for(var i = 0; i< oSpans.length; i++){
oSpans[i].onclick = function(){
// 5.3 移除当前的li标签
oUl.removeChild(this.parentNode)
count--;
}
}
}
function sum(){
alert('一共发布了'+count+'条留言');
}
</script>
</html>