前端–JavaScript DOM
1. DOM的概念
前面我们了解到JS的三个部分:
- ECMAScript 语法。
- DOM
document object model 文档(网页)对象模型
。DOM 有什么用?就是为了操作 HTML 中的元素。
比如说我们要通过 JS 把这个网页的标题改了,直接这样就可以了:document.title = 'it❤ld';
- 通过 HTML DOM,JavaScript 能够访问和改变 HTML 文档的所有元素。
- 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。
- HTML DOM 模型被结构化为对象树。对象的 HTML DOM 树:
通过这个对象模型,JavaScript 获得创建动态 HTML 的所有力量:
- JavaScript 能改变页面中的所有 HTML 元素
- JavaScript 能改变页面中的所有 HTML 属性
- JavaScript 能改变页面中的所有 CSS 样式
- JavaScript 能删除已有的 HTML 元素和属性
- JavaScript 能添加新的 HTML 元素和属性
- JavaScript 能对页面中所有已有的 HTML 事件作出反应
- JavaScript 能在页面中创建新的 HTML 事件
- 什么是 HTML DOM?HTML DOM 是 HTML 的标准对象模型和编程接口。它定义了:
- 作为对象的 HTML 元素
- 所有 HTML 元素的属性
- 访问所有 HTML 元素的方法
- 所有 HTML 元素的事件
换言之:HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准。
- BOM browser object model 浏览器对象模型。
1.1 HTML DOM属性和方法
HTML DOM 方法是您能够(在 HTML 元素上)执行的动作。
HTML DOM 属性是您能够设置或改变的HTML 元素的值。
- 在 DOM 中,所有 HTML 元素都被定义为对象。
- 编程界面是每个对象的属性和方法。
- 属性是您能够获取或设置的值(就比如改变 HTML 元素的内容)。
- 方法是您能够完成的动作(比如添加或删除 HTML 元素)
1.2 HTML DOM Document 对象☆
如果您希望访问 HTML 页面中的任何元素,那么您总是从访问 document 对象开始。
查找 HTML 元素
- 通过 id 查找 HTML 元素
- 通过标签名查找 HTML 元素
- 通过类名查找 HTML 元素
- 通过 CSS 选择器查找 HTML 元素
- 通过 HTML 对象集合查找 HTML 元素
方法 | 描述 |
---|---|
document.getElementById(id) | 通过元素 id 来查找元素 |
document.getElementsByTagName(name) | 通过标签名来查找元素 |
document.getElementsByClassName(name) | 通过类名来查找元素 |
document.querySelectorAll(id、类名、类型、属性、属性值等等); | 通过 CSS 选择器查找 HTML 元素 |
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>获取dom对象的方式</title>
</head>
<body>
<input type="text" id="first">
<input type="text" class="tex">
<input type="text" class="tex">
<input type="text" class="tex">
<input type="text" name="username">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<script>
//根据元素的id获取对象。不是数组。
var elementById = document.getElementById("first");
//根据元素的name属性值来获取对象。拿到的是一个数组。
var elementsByName = document.getElementsByName("username");
//根据类名来获取对象的元素。拿到的是一个数组。 ie 8以及8版本一下都不支持。
var elementsByClassName = document.getElementsByClassName("tex");
console.log(elementsByClassName.length);
// 根据元素的标签名获取对象。拿到的是数组。
var ele = document.getElementsByTagName("input");
// 根据id查询 前面加上#号,
// 根据class属性来查询,前面加上.,
// 根据标签名查询,前面什么也不加,直接写标签名。
// 不是数组。取得查询到的第一条数据。
// ie 7以及7版本一下都不支持。
var element = document.querySelector("tex");
// console.log(element.type);
//返回结果是一个数组。不是数组。取得查询到的第一条数据。
// ie 7以及7版本一下都不支持。
var element1 = document.querySelector(".tex");
console.log(element1);
</script>
</body>
</html>
改变 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 输出流 |
添加事件处理程序
方法 | 描述 |
---|---|
document.getElementById(id).onclick = function(){code} | 向 onclick 事件添加事件处理程序 |
2.DOM 事件
2.1 事件三要素
事件源:
被触发的事物(元素)。事件类型:
用户的操作行为(单击,双击,鼠标移入,鼠标移出)。执行当前事件的命令:
被触发后的操作,叫做事件的处理函数。
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>操作</title>
</head>
<body>
<!--第一种方式:行内式-->
<!--此种写法存在问题:耦合度太高。
ECMAScript代码和dom元素写到一起了,维护比较困难。-->
<button onclick="alert('哈哈哈哈哈1')">按钮1</button>
<!-- 第二种方式:行内式,函数定义外面-->
<!-- button是事件源,onclick是事件的类型,执行的函数是fn1-->
<button onclick="fn1('哈哈哈哈哈哈2')">按钮2</button>
<script>
function fn1(para) {
alert(para);
}
</script>
<!-- 第三种:外置函数式。所有关于事件的代码全部写到标签外。便于维护。 -->
<button id="btn">按钮2</button>
<script>
console.log(document);
var father = {"name": "duanduan", "age": 19};
var son = {name: "miaomiao", age: 18, father: father};
console.log(son);
console.log(son.father);
console.log("-----------在网页中,通过标签的id来获取标签对象。-----------");
var btn = document.getElementById("btn");
console.log(btn);
console.dir(btn);
console.dir(btn.__proto__);
console.dir(btn.__proto__.__proto__);
console.dir(btn.__proto__.__proto__.__proto__);
console.dir(btn.__proto__.__proto__.__proto__.__proto__);
console.dir(btn.__proto__.__proto__.__proto__.__proto__.__proto__);
console.dir(btn.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__);
console.dir(btn.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__);//null
// 事件源.事件类型=事件执行的代码。
btn.onclick = function () {
alert("Hello Justweb")
}
</script>
</body>
</html>
2.2 事件的执行过程
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>事件执行的过程</title>
</head>
<body>
<button id="btn">按钮</button>
<script>
var num = 0;
var btn = document.getElementById("btn");
console.log("函数前num = " + num);
btn.onclick = function () {
num++;
console.log("触发时间后的num = " + num);
};
num = 20;
console.log("重新赋值后的num = "+ num);
</script>
</body>
</html>
2.3 onclick 事件☆
点击设置属性/标签内容
设置属性
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>点击设置属性</title>
</head>
<body>
<button id="btn">展示图片</button>
<div>
<img src=" " alt="" id="img">
</div>
<script>
var btn = document.getElementById("btn");
var img1 = document.getElementById("img");
console.dir(img1);
btn.onclick = function () {
img1.src = "../images/liuyan.jpg";
img1.width = 400;
img1.height = 600;
}
</script>
</body>
</html>
设置标签内容
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>点击设置标签内容</title>
</head>
<body>
<button id="btn">按钮</button>
<div>
<a href="http://www.baidu.com" target="_blank" id="taobao">百度</a>
</div>
<script>
//获取id为btn的dom对象
var btn = document.getElementById("btn");
//获取id为taobao的<a>标签的对象
var taobao = document.getElementById("taobao");
console.dir(taobao);
btn.onclick = function () {
taobao.href = "http://www.taobao.com";
// innerHTML 会将文本中的标签解析成html标签,innerText 不会解析 文本中的标签。
taobao.innerText = "<strong>淘宝<strong/>"
// taobao.innerHTML="<strong>淘宝<strong/>"
}
</script>
</body>
</html>
单击改变所有标签的内容
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>单击改变所有标签的内容</title>
<style>
* {
margin: 0;
padding: 0;
font-size: 18px;
}
ul, li {
list-style: none;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<ul>
<li class="listyle">01</li>
<li class="listyle">02</li>
<li class="listyle">03</li>
<li class="listyle">04</li>
<li class="listyle">05</li>
<li class="listyle">06</li>
<li class="listyle">07</li>
</ul>
<script>
// 根据id获取dom对象
var btn = document.getElementById("btn");
// 根据标签名获取对象,结果是个数组
// var libq1 = document.getElementsByTagName("li");
// 根据标类名获取对象,结果是个数组。
var lis = document.getElementsByClassName("listyle");
btn.onclick = function () {
// 遍历标签数组
for (let i = 0; i < lis.length; i++) {
lis[i].innerText = "你好";
}
};
</script>
</body>
</html>
单击按钮改变表单的类型
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>单击按钮改变表单的类型</title>
</head>
<body>
<input type="button" value="按钮" id="btn">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<script>
var btn = document.getElementById("btn");
var inputs = document.getElementsByTagName("input");
btn.onclick = function () {
for (let i = 0; i < inputs.length; i++) {
// 通过input对象名.属性 可以获取dom对象的属性值。
console.log(inputs[i].type);
if (inputs[i].type === 'text') {
//通过input对象名.属性 = 值 可以对dom对象的属性赋值。
inputs[i].type = "checkbox";
}
}
}
</script>
</body>
</html>
单击img控制台输出自己的宽度
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>单击img弹出自己的宽度</title>
</head>
<body>
<img src="../images/111.jpg" alt="" width="100" id="img1">
<img src="../images/222.jpg" alt="" width="200" id="img2">
<img src="../images/333.jpg" alt="" width="300" id="img3">
<script>
// 获取id为img的dom对象,如果有500张照片,这种方式做不了。
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
imgs[i].onclick = function () {
//this指的是事件的调用者,其实就是指向事件源。
console.log(this.width);
};
}
</script>
</body>
</html>
单击获取标签的索引号
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>单击获取标签的索引号</title>
<script>
/**
* * 事件函数中无法直接获取到当前标签对象的索引。
* 1.在循环中,将每个标签的索引号设置到标签的属性中
* 2.在触发事件的时候通过this去获取标签属性的索引值。
*/
</script>
</head>
<body>
<img src="../images/111.jpg" alt="" width="100" id="img1">
<img src="../images/111.jpg" alt="" width="200" id="img2">
<img src="../images/111.jpg" alt="" width="300" id="img3">
<script>
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
// 给每个标签索引值设置到title属性中。
// 注意不要设置在imgs[i].οnclick=function(){}中
// imgs[i].title = i;//方法一
imgs[i].setAttribute("num", i);//方法二
imgs[i].onclick = function () {
// 通过当前标签获取属性中的索引值。
// console.log(this.title);
console.log(this.getAttribute("num"));
console.log(this.width);
}
}
</script>
</body>
</html>
自定义属性
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>自定义属性</title>
<script>
/**
* 标签自带的属性:可以通过对象名.属性名设置,
* 也可以通过对象名.setAttribute()设置。
* 可以通过对象名.属性名获取,可以通过对象名.getAttribute()获取。
*/
</script>
</head>
<body>
<img src="../images/liuyan.jpg" alt="" title="" id="img1">
<script>
var img1 = document.getElementById("img1");
// img1.title="11111";
// console.log(img1.title);
// img1.setAttribute("title",1111);
// console.log(img1.title);
// 自定义属性:设置值的时候需要通过setAttribute()这个方法去设置。
img1.setAttribute("num", "22");
// 自定义属性:获取值得时候需要通过getAtribute()这个方法去获取。
console.log(img1.getAttribute("num"));
</script>
</body>
</html>
通过JS给标签设置样式
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>通过JS给标签设置样式</title>
</head>
<body>
<button>设置高度</button>
<button>设置宽度</button>
<button>设置背景色</button>
<button>三变</button>
<button>读取</button>
<div id="box"></div>
<script>
var btns = document.getElementsByTagName("button");
var box = document.getElementById("box");
console.dir(box);//对象
btns[0].onclick = function () {
box.style.width = "300px";
};
btns[1].onclick = function () {
box.style.height = "300px";
};
btns[2].onclick = function () {
box.style.backgroundColor = "lightgreen";
};
btns[3].onclick = function () {
box.style.width = "300px";
box.style.height = "300px";
box.style.backgroundColor = "green";
};
btns[4].onclick = function () {
console.log(box.style.width);
console.log(box.style.height);
console.log(box.style.backgroundColor);
}
</script>
</body>
</html>
排他思想
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>排他思想</title>
</head>
<body>
<button>苗子</button>
<button>苗子</button>
<button>苗子</button>
<button>苗子</button>
<button>段子</button>
<button>苗子</button>
<button>苗子</button>
<button>苗子</button>
<script>
var btns = document.getElementsByTagName("button");
// 排他思想,推荐使用
// for (var i = 0; i < btns.length; i++) {
// btns[i].οnclick=function(){
// for (var j = 0; j < btns.length; j++) {
// btns[j].innerText="苗子";
// }
// this.innerText="段子";
// }
// }
// 不推荐使用,通过索引号和记录的上一次点击的索引号,来解决此类问题。
var pre = 4;
for (var i = 0; i < btns.length; i++) {
btns[i].setAttribute("num", i);
}
for (var i = 0; i < btns.length; i++) {
for (var j = 0; j < btns.length; j++) {
btns[i].onclick = function () {
btns[pre].innerText = "苗子";
this.innerText = "段子";
pre = this.getAttribute("num");
}
}
}
</script>
</body>
</html>
一个按钮显示隐藏切换
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>一个按钮显示隐藏切换</title>
<style>
* {
margin: 2px;
padding: 10px;
}
div {
width: 100px;
height: 100px;
background-color: #ff816b;
}
</style>
</head>
<body>
<button>显示</button>
<button>隐藏</button>
<div id="box"></div>
<script>
var btns = document.getElementsByTagName("button");
var box = document.getElementById("box");
// css样式中,display none 隐藏,block显示。
btns[0].onclick = function () {
box.style.display = "block";
};
btns[1].onclick = function () {
box.style.display = "none";
};
</script>
</body>
</html>
页面开关灯
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>页面开关灯</title>
</head>
<body>
<button id="btn">黑夜</button>
<script>
var btn = document.getElementById("btn");
var flag = true;
btn.onclick = function () {
if (flag) {
document.body.style.backgroundColor = "black";
btn.innerText = "白天";
flag = !flag;
} else {
document.body.style.backgroundColor = "white";
btn.innerText = "黑天";
flag = !flag;
}
}
</script>
</body>
</html>
通过css类名添加样式
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>通过css类名添加样式</title>
<style>
.box {
width: 200px;
height: 100px;
background-color: #ff9f2c;
}
.box1 {
line-height: 100px;
text-align: center;
margin: 0 auto;
}
</style>
</head>
<body>
<button id="btn">添加box样式</button>
<button id="btn1">添加box1的样式</button>
<button id="btn2">获取div的class样式</button>
<div id="box">
苗子段子
</div>
<script>
var btn = document.getElementById("btn");
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var box = document.getElementById("box");
/*
* 正常来说 设置class属性应该使用class作为属性名,
* 但是因为class是js中的保留字,所以不能被使用,使用className代替。
* 通过dom对象.className 进行赋值是对值得覆盖。不是追加。
*/
btn.onclick = function () {
box.className = "box";
};
btn1.onclick = function () {
box.className = "box box1";
};
btn2.onclick = function () {
console.log(box.className);
}
</script>
</body>
</html>
全选取消反选
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>全选取消反选</title>
<style>
* {
margin: 0;
padding: 10px;
}
ul, li {
list-style: none;
}
</style>
</head>
<body>
<button>全选</button>
<button>取消</button>
<button>反选</button>
<ul>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
<li><input type="checkbox"></li>
</ul>
<script>
var btns = document.getElementsByTagName("button");
var inputs = document.getElementsByTagName("input");
console.log(inputs[0].checked);
//全选
btns[0].onclick = function () {
for (var i = 0; i < inputs.length; i++) {
inputs[i].checked = true;
}
};
//取消
btns[1].onclick = function () {
for (var i = 0; i < inputs.length; i++) {
inputs[i].checked = false;
}
};
//反选
btns[2].onclick = function () {
for (var i = 0; i < inputs.length; i++) {
// true变成false,false修改成true; low
// if(!inputs[i].checked){
// inputs[i].checked=true;
// }else{
// inputs[i].checked=false;
// }
inputs[i].checked = !inputs[i].checked;
}
}
</script>
</body>
</html>
通过css的class样式的排他思想
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>通过css的class样式的排他思想</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
button {
float: left;
width: 100px;
height: 100px;
display: block;
background-color: #FBBC05;
border: 1px solid #ED784A;
margin-left: 20px;
}
.square {
background-color: #FBBC05;
outline: none;
}
.circle {
border-radius: 50%;
background-color: #ED784A;
}
</style>
</head>
<body>
<button class="circle">苗子</button>
<button>苗子</button>
<button>苗子</button>
<button>苗子</button>
<button>段子</button>
<button>苗子</button>
<button>苗子</button>
<button>苗子</button>
<script>
var btns = document.getElementsByTagName("button");
// 排他思想,推荐使用
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
// 1.把所有的按钮的内容全部更新为“苗子”
for (var j = 0; j < btns.length; j++) {
btns[j].className = "square";
btns[j].innerText = "苗子";
}
// 把本次点击的按钮内容改成“段子”
this.className = "circle";
this.innerText = "段子";
}
}
</script>
</body>
</html>
隔行变色
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>隔行变色</title>
<style>
* {
margin: 0;
padding: 0;
}
ul, li {
list-style: none;
}
</style>
</head>
<body>
<ul id="gh">
<li>01</li>
<li>02</li>
<li>03</li>
<li>04</li>
<li>05</li>
<li>06</li>
</ul>
<script>
// 通过id获取到ul标签对象,得到的结果直接是个对象,不是数组.
var ulobj = document.getElementById("gh");
// 通过id为gh的ul标签,然后查找ul标签下面所有的li标签对象。 getElementsByTagName()得到的结果是个数组。
var lis = ulobj.getElementsByTagName("li");
for (let i = 0; i < lis.length; i++) {
if (i % 2 == 0) {
lis[i].style.backgroundColor = "lightgreen";
} else {
lis[i].style.backgroundColor = "lightblue";
}
}
</script>
</body>
</html>
阻止超链接跳转
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>阻止超链接跳转</title>
</head>
<body>
<!--阻止a标签跳转,第一种方式,删除href属性-->
<a target="_blank">淘宝</a>
<br>
<!--第二种方式,onclick中只要匿名函数的返回值为false,那么当前的a标签不会跳转。-->
<a href="http://www.taobao.com" onclick="return false" target="_blank">淘宝</a>
<a href="http://www.taobao.com" id="a1" target="_self">淘宝</a>
<a href="http://www.taobao.com" onclick="return fn()" target="_blank">淘宝</a>
<br>
<!--第三种方式:在a标签的href属性中设置:javascript:void(0);-->
<a href="javascript:void(0);" target="_blank">淘宝</a>
<script>
/**
* 不希望a标签跳转
*/
var aobj = document.getElementById("a1");
aobj.onclick = function () {
return false;
};
function fn() {
if (true) {
}
return false;
}
</script>
</body>
</html>
美女画廊
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>美女画廊</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
padding-top: 5px;
margin: 20px 0px 20px 20px;
}
.container {
width: 500px;
height: 470px;
margin: 100px auto 0px;
/*background-color: #52ff90;*/
background: linear-gradient(#ff7381, lightblue);
}
ul, li {
list-style: none;
}
#wpic > ul > li {
margin-left: 20px;
float: left;
}
img {
display: block;
}
.clearfix:after {
content: "";
display: block;
clear: both;
}
#bigImage {
margin: 20px 0px 20px 20px;
}
</style>
</head>
<body>
<div class="container">
<div>
<h1>美女画廊</h1>
</div>
<div id="wpic">
<ul class="clearfix">
<li><a href="images/1.jpg">
<img src="images/1-small.jpg" alt="" width="100">
</a>
</li>
<li><a href="images/2.jpg">
<img src="images/2-small.jpg" alt="" width="100">
</a>
</li>
<li><a href="images/3.jpg">
<img src="images/3-small.jpg" alt="" width="100">
</a>
</li>
<li><a href="images/4.jpg">
<img src="images/4-small.jpg" alt="" width="100">
</a>
</li>
</ul>
</div>
<div>
<img src="" alt="" width="460" height="300" id="bigImage">
</div>
</div>
<script>
//获取所有的a标签
var aes = document.getElementById("wpic").getElementsByTagName("a");
//获取目标图片对象
var bigImage = document.getElementById("bigImage");
//遍历a标签对象
for (var i = 0; i < aes.length; i++) {
aes[i].onclick = function () {
console.log(this.href);
//拿到a标签的href属性,并且赋值给目标图片。
bigImage.src = this.href;
// 阻止a标签跳转。
return false;
}
}
</script>
</body>
</html>
2.4 onmouseover 和 onmouseout 事件
鼠标移入移出二维码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>鼠标移入移出二维码</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 50px;
height: 50px;
background: url("images/bgs.png") -159px -51px no-repeat;
position: fixed;
right: 0;
top: 50%;
margin-top: -25px;
/ / 因为,box高为50px
}
#erBig {
position: relative;
/*left:-120px;*/
}
</style>
</head>
<body>
<div class="box" id="erSmall">
<img src="images/456.png" alt="" id="erBig" style="display:none" width="120">
</div>
<script>
// 获取小二维码的对象
var box = document.getElementById("erSmall");
// 获取大的二维码的对象
var erBig = document.getElementById("erBig");
//获取图片的宽度
var erBigWidth = erBig.width;
console.log(erBigWidth);
// 设置大二维码图片的偏移位置。
erBig.style.left = (-erBigWidth) + "px";
// 当鼠标移入的时候,触发事件:
// 1.修改小二维码的精灵图做坐标,
// 2.将大二维码的展示。
box.onmouseover = function () {
box.style.backgroundPositionX = "-220px";
erBig.style.display = "block";
};
//当鼠标移出的时候,触发事件:
// 1.修改小二维码的精灵图做坐标,
// 2.将大二维码的隐藏。
box.onmouseout = function () {
box.style.backgroundPositionX = "-159px";
erBig.style.display = "none";
}
</script>
</body>
</html>
鼠标移入移出二维码(类名版)
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>鼠标移入移出二维码(类名版)</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 50px;
height: 50px;
background: url(images/bgs.png) -159px -51px no-repeat;
position: fixed;
right: 0px;
top: 50%;
margin-top: -25px;
}
.redbox {
background: url(images/bgs.png) -220px -51px no-repeat;
}
#erBig {
position: relative;
}
.erBigHidden {
display: none;
}
.erBigShow {
display: block;
}
</style>
</head>
<body>
<div class="box" id="erSmall">
<img src="images/456.png" alt="" id="erBig">
</div>
<script>
// 获取小二维码的对象
var box = document.getElementById("erSmall");
// 获取大的二维码的对象
var erBig = document.getElementById("erBig");
// 获取图片的宽度
var erBigWidth = erBig.width;
console.log(erBigWidth);
// 设置大二维码图片的偏移位置。
erBig.style.left = -erBigWidth + "px";
// 当鼠标移入的时候,触发事件:1.修改小二维码的精灵图做坐标,
// 2.将大二维码的展示。
box.onmouseover = function () {
box.className = "box redbox";
erBig.className = "erBigShow";
};
//当鼠标移出的时候,触发事件:1.修改小二维码的精灵图做坐标,
// 2.将大二维码的隐藏。
box.onmouseout = function () {
box.className = "box ";
erBig.className = "erBigHidden"
}
</script>
</body>
</html>
隔行变色(升级版)
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>隔行变色(升级版)</title>
<style>
* {
margin: 0;
padding: 0;
}
ul, li {
list-style: none;
}
</style>
</head>
<body>
<ul id="gh">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script>
// 通过id获取到ul标签对象,得到的结果直接是个对象,不是数组.
var ulobj = document.getElementById("gh");
//通过id为gh的ul标签,然后查找ul标签下面所有的li标签对象。 getElementsByTagName()得到的结果是个数组。
var lis = ulobj.getElementsByTagName("li");
for (let i = 0; i < lis.length; i++) {
lis[i].setAttribute("num", i);
if (i % 2 === 0) {
lis[i].style.backgroundColor = "lightgreen";
} else {
lis[i].style.backgroundColor = "pink";
}
lis[i].onmouseover = function () {
var num = this.getAttribute("num");
if (num % 2 === 0) {
this.style.backgroundColor = "gray";
} else {
this.style.backgroundColor = "#AA6688";
}
};
lis[i].onmouseout = function () {
var num = this.getAttribute("num");
if (num % 2 == 0) {
this.style.backgroundColor = "lightgreen";
} else {
this.style.backgroundColor = "pink";
}
}
}
</script>
</body>
</html>
3. JS HTML DOM 元素(节点)
- 元素节点:标签 element
- 属性节点:标签中的属性 property
- 文本节点:标签中的文本内容
- 注释节点:标签中的注释的内容
元素一定是节点,但是节点不一定是元素。document > node > element
补充:
/** * 高版本的浏览器 * 火狐,谷歌,ie 9 ,10 ,11 * 低版本的浏览器 * ie 6 , 7, 8 */
3.1 节点的属性
在文档对象模型中,每个节点都是一个对象。DOM节点有三个重要的属性:
- 节点类型:是只读的
- 节点名称:是只读的
- 节点值:
节点属性 | 元素 | 标签中的属性 | 文本的内容 | 注释 |
---|---|---|---|---|
nodeType节点类型 | 1 | 2 | 3 | 8 |
nodeName节点名称 | 大写的标签名 | 小写的属性名 | #text | #comment |
nodeValue节点值 | undefined/null | 属性值 | 文本的内容(文本,空格,换行) | 注释的内容 |
3.2 获取父/子节点/元素
子节点:childNodes (儿子节点,不包含孙子)
- 高版本浏览器:元素 文本(换行,空格,文本) 注释
- 低版本浏览器: 元素 文本(不包含换行和空格)注释
children: 获取子元素
- 高版本浏览器:元素
- 低版本浏览器:元素 注释
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>子节点和子元素</title>
</head>
<body>
<div id="box">你好
<!--注释的内容-->
<h2 title="singer">周杰伦</h2>
<ul>
<li>稻香</li>
<li>夜曲</li>
<li>东风破</li>
<li>龙卷风</li>
<li>菊花台</li>
</ul>
<h3>方文山</h3>
</div>
<script>
// 获取box的元素节点
var box = document.getElementById("box");
// 获取box元素节点下面的所有的子节点
var boxChilds = box.childNodes;
console.log(boxChilds);
//遍历所有的子节点
for (let i = 0; i < boxChilds.length; i++) {
console.log(boxChilds[i]);
// //子节点的nodeType 节点类型
// console.log(boxChilds[i].nodeType);
// //nodeName 节点的名称
// console.log(boxChilds[i].nodeName);
// //nodeValue 节点的值。
// console.log(boxChilds[i].nodeValue);
console.log("---------------------");
}
//children直接拿到所有的子元素。
var children = box.children;
console.log("---------------------" + children.length);
// 低版本浏览器是4
// 高版本浏览器是3
</script>
</body>
</html>
- 父节点:
parentNode
其实就是父元素(标签),所有的浏览器都可以使用。- 父元素:
parentElement
拿到父元素,所有的浏览器都可以使用。开发惯用
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>父节点和父元素</title>
</head>
<body>
<div id="box">你好
<!--注释的内容-->
<h2 title="singer">周杰伦</h2>
<ul>
<li id="gun">稻香</li>
<li>夜曲</li>
<li>东风破</li>
<li>龙卷风</li>
<li>菊花台</li>
</ul>
<h3>方文山</h3>
</div>
<script>
var gun = document.getElementById("gun");
//获取父节点
var parentNode = gun.parentNode;
console.log(parentNode);
//获取父元素
var parentElement = gun.parentElement;
console.log(parentElement);
</script>
</body>
</html>
第一个子节点 firstChild
- 高版本浏览器: 元素 文本(文本,空格,换行) 注释
- 低版本浏览器 元素 文本(不包含空格和换行) 注释
第一个子元素:firstElementChild
- 高版本浏览器: 第一个元素
- 低版本浏览器: undefined
- 只要不在标签内容写注释内容,firstElementChild拿到的是都是元素。
注意元素和节点的区别!
高版本浏览器认识firstElementChild
低版本浏览器认识firstChild
function getFirstElementChild(obj){ //判断是不是高版本浏览器 if(obj.firstElementChild){ return obj.firstElementChild; }else{ //如果是低版本浏览器 var nodeE = obj.firstChild; while(nodeE.nodeType != 1){ nodeE = nodeE.nextSibling; } return nodeE; } }
list.nextSibling;
拿到当前节点的下一个节点。
list.nextElementSibling;
拿到当前节点的下一个元素。
list.previousElementSibling;
拿到当前节点的上一个兄弟节点
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>其他获取节点和元素的方式</title>
</head>
<body>
<div id="box">
你好
<!-- 注释的内容 -->
<h2 title="singer">周杰伦</h2>
<!-- 注释的内容 -->
<ul id="list">
<!-- 注释内容 -->
<li id="gun">双截棍</li>
<li>龙卷风</li>
<li>东风破</li>
<li>夜曲</li>
<li>菊花台</li>
</ul>
<!-- 注释的内容 -->
<h3>方文山</h3>
</div>
<script>
// 拿到ul标签的元素节点对象
var list = document.getElementById("list");
//拿到的是第一个子节点
var firstChild = list.firstChild;
console.log(firstChild);
// 拿到第一个子元素。
var firstElementChild = list.firstElementChild;
console.log(firstElementChild);
// 拿到最后一个子节点
var lastChild = list.lastChild;
console.log(lastChild);
// 拿到最后一个子元素
var lastElementChild = list.lastElementChild;
console.log(lastElementChild);
// 拿到当前节点的下一个节点。
var nextSibling = list.nextSibling;
console.log(nextSibling);
// 拿到当前节点的下一个元素。
var nextElementSibling = list.nextElementSibling;
console.log(nextElementSibling);
// 拿到当前节点的上一个兄弟节点
var previousElementSibling = list.previousElementSibling;
console.log(previousElementSibling);
</script>
</body>
</html>
第一个子节点 lastChild
- 高版本浏览器: 元素 文本(文本,空格,换行) 注释
- 低版本浏览器 元素 文本(不包含空格和换行) 注释
第一个子元素:lastElementChild
- 高版本浏览器: 第一个元素
- 低版本浏览器: undefined
- 只要不在标签内容写注释内容,lastElementChild拿到的是都是元素。
高版本浏览器认识lastElementChild
低版本浏览器认识lastChild
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>lastChild兼容性问题的解决方案、</title>
</head>
<body>
<div id="box">
nihao
<!--注释的内容-->
<h2 title="singer">周杰伦</h2>
<!--注释的内容-->
<ul id="list">
sbfw
<li id="gun">双截棍</li>
<li>龙卷风</li>
<li>东风破</li>
<li>夜曲</li>
<li>菊花台</li>
sbdz
</ul>
<!--注释的内容-->
<h3>方文山</h3>
</div>
<script>
//拿到ul标签的元素节点对象
var list = document.getElementById("list");
// 拿到的是最后一个子节点
var lastChild = list.lastChild;
console.log(lastChild);
// 拿到最后一个子元素。
var lastElementChild = list.lastElementChild;
console.log(lastElementChild);
var lastElementChild = getLastElementChild(list);
console.log(lastElementChild);
function getLastElementChild(obj) {
//判断是不是高版本浏览器
if (obj.lastElementChild) {
return obj.lastElementChild;
} else {
//如果是低版本浏览器
var nodeE = obj.lastChild;
while (nodeE && nodeE.nodeType != 1) {
nodeE = nodeE.previousSibling;
}
return nodeE;
}
}
</script>
</body>
</html>
3.3 创建节点
第一种方式创建一个节点
虽然能够添加节点,但是存在问题:
document.write()只能在页面加载的过程中使用,
- 如果页面加载完成后,使用的话会将其他的dom都覆盖掉。
<button id="btn">按钮</button>
<script>
//页面加载的时候向浏览器端添加<h1>hello justweb1</h1>
document.write("<h1>hello justweb1<h1>");
var btn = document.getElementById("btn");
btn.onclick = function () {
// 页面加载完成后,被触发onclick事件的时候往浏览器端写入内容
document.write("<h1>hello justweb2<h1>");
}
</script>
第二种方式创建一个节点
<body>
<button id="btn">按钮</button>
<div id="di">
<h1>hello justweb1</h1>
</div>
<script>
var btn = document.getElementById("btn");
var di = document.getElementById("di");
btn.onclick = function () {
// innerText 是设置内容,内容会原样输出。
// innerHTML 是设置内容,如果有html标签,会解析标签。
// 将html标签解析成对应的效果展示出来。
// di.innerText="hello justweb2";
di.innerHTML = "<h1>hello justweb2<h1/>"
}
</script>
</body>
通过第二种方式动态的添加节点
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>通过第二种方式动态的添加节点</title>
</head>
<body>
<button id="btn">按钮</button>
<div>
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<script>
var btn = document.getElementById("btn");
var list = document.getElementById("list");
var num = 4;
btn.onclick = function () {
var str = list.innerHTML;
str = str + "<li>" + num + "</li>";
list.innerHTML = str;
num++;
}
</script>
</body>
</html>
通过第二种方式动态的添加节点2
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>通过第二种方式动态的添加节点2</title>
</head>
<body>
<button id="btn">按钮</button>
<div id="di">
</div>
<script>
var btn = document.getElementById("btn");
var di = document.getElementById("di");
var studentjson = [{"name": "张三", "age": 15, "sex": "男"}, {"name": "李四", "age": 15, "sex": "男"}, {
"name": "王五",
"age": 15,
"sex": "男"
}, {"name": "赵六", "age": 15, "sex": "男"}, {"name": "苗子", "age": 17, "sex": "女"}];
// 拼接字符串
var str = "";
btn.onclick = function () {
//先拼接一个table
str += "<table border='1' cellspacing='0' width='500'>";
//数组的长度就是表格tr的数量行数。
for (let i = 0; i < studentjson.length; i++) {
str += "<tr height='50'>";
//对象属性的个数就是td的个数,列数。
for (var par in studentjson[i]) {
str += "<td>";
str += studentjson[i][par];
str += "</td>"
}
str += "</tr>"
}
//taable结尾
str += "</table>";
di.innerHTML = str;
}
</script>
</body>
</html>
遍历对象的属性:
<script>
var obj = {"name": "张三", "age": 15, "sex": "男"};
for (var i in obj) {
console.log(obj[i]);
}
</script>
第三种添加节点的方式
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>第三种添加节点的方式</title>
<style>
ul,
li{
list-style: none;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div id="box">
</div>
<script>
// 获取按钮的对象
var btn = document.getElementById('btn');
// 获取div盒子的对象
var box = document.getElementById('box');
var stars = ["谢霆锋", "陈冠希", "阿娇", "张柏芝", "涛哥"];
// 创建一个ul对象
var ul = document.createElement("ul");
// 将ul对象添加到box对象中。
box.appendChild(ul);
var num = 1;
//按钮的单击事件
btn.onclick = function () {
//循环创建li节点
for (let i = 0; i < stars.length; i++) {
//创建一个li节点对象
var li = document.createElement("li");
//给li节点对象设置num属性,为了隔行变色
li.setAttribute("num", num);
//隔行变色
if (num % 2 == 0) {
li.style.backgroundColor = "pink";
} else {
li.style.backgroundColor = "lightgreen";
}
li.innerText = stars[i];
box.appendChild(li);
num++;
//鼠标移入隔行变色
li.onmouseover = function () {
// 获取li的num属性,这里一定要是用的是this,不能使用li标签 。
if (this.getAttribute("num") % 2 == 0) {
this.style.backgroundColor = "purple";
} else {
this.style.backgroundColor = "gray";
}
};
//鼠标移除,颜色恢复默认效果。
li.onmouseout = function () {
if (this.getAttribute("num") % 2 == 0) {
this.style.backgroundColor = "pink";
} else {
this.style.backgroundColor = "lightgreen";
}
}
}
}
</script>
</body>
</html>
3.4 节点的插入替换和删除
以下下方法都是
针对于父元素调用的
,操作的是子元素。
insertBefore
在标签中添加节点对象。replaceChild
替换节点。removeChild
删除节点。
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>节点的常用属性</title>
<style>
ul,
li{
list-style: none;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div id="box">
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
</div>
<script>
var btn = document.getElementById("btn");
var list = document.getElementById("list");
var num = 1;
btn.onclick = function () {
var li = document.createElement("li");
li.innerHTML = num++;
// appendChild追加,在元素子节点最后添加当前的节点。
// list.appendChild(li);
/***
* 插入节点
* 往标签中添加节点。
* 第一个参数:新结点。
* 第二个参数:参照节点。
*/
list.insertBefore(li, list.firstElementChild);
list.insertBefore(li, list.lastElementChild);
/**
* 替换节点:
* replaceChild(新结点,被替换的节点);
*/
list.replaceChild(li, list.lastElementChild);
/**
* 删除节点
* list.removeChild(被删除的节点);
*/
list.removeChild(list.firstElementChild);
}
</script>
</body>
</html>
4. 小案例☆
4.1 HTML架子
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>电影案例</title>
<link rel="stylesheet" href="../movie.css">
</head>
<body>
<div id="box">
<button id="btn1" class="btn">添加数据</button>
<table>
<thead>
<tr>
<td>电影</td>
<td>领衔主演</td>
<td>已看过</td>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td>西红柿首富</td>
<td>沈腾</td>
<td class="del">删除</td>
</tr>
<tr>
<td>分手大师</td>
<td>某某</td>
<td class="del">删除</td>
</tr>
<tr>
<td>奇迹男孩</td>
<td>某某</td>
<td class="del">删除</td>
</tr>
</tbody>
</table>
</div>
<div class="modal" id="modal">
<div class="add">
<div class="first">
添加数据
<span id="close">×</span>
</div>
<div class="second">
电影名称:<input type="text" placeholder="请输入电影名称" id="film"></div>
<div class="third">
领衔主演:<input type="text" id="actor">
</div>
<div class="fourth">
<button id="finish">完成</button>
</div>
</div>
</div>
<script src="../movie.js"></script>
</body>
</html>
4.2 movie.css样式
* {
margin: 0;
padding: 0;
// 默认是content-box
box-sizing: border-box;
font-size: 16px;
}
#box {
margin: 100px auto 0;
width: 300px;
}
table {
width: 300px;
border-spacing: 0px;
text-align: center;
border-collapse: collapse;
// 删除层叠部分
}
th, td {
border: 1px solid #000000;
padding: 5px 0px;
}
th {
color: white;
background-color: #3b8fc7;
}
/*为什么不显示蓝色*/
#box > .btn {
width: 100px;
height: 30px;
font-size: 13px;
line-height: 30px;
}
/*height:100%后面加//会出现问题
*/
.modal {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: none;
}
.modal > .add {
position: fixed;
width: 470px;
height: 280px;
background-color: #fff;
top: 50%;
left: 50%;
margin-top: -140px;
margin-left: -235px;
}
.modal > .add > .first {
height: 30px;
background-color: #ececec;
text-align: center;
line-height: 30px;
font-weight: 700;
font-size: 18px;
}
.modal > .add > .first > span {
position: absolute;
right: 10px;
cursor: pointer;
}
.modal > .add > .second, .modal > .add > .third {
padding: 15px 0 0 15px;
}
.modal > .add > .second > input, .modal > .add > .third > input {
border: 1px solid #ececec;
width: 300px;
height: 30px;
outline: none;
border-radius: 5px;
}
.modal > .add > .fourth > button {
width: 100px;
height: 30px;
margin-top: 50px;
margin-left: 165px;
}
table > tr > td.del {
color: blue;
cursor: pointer;
text-decoration: underline;
}
4.3 movie.js
// 添加数据按钮的对象
var btn1 = document.getElementById("btn1");
// 模态框的关闭按钮
var close = document.getElementById("close");
//完成按钮对象
var finish = document.getElementById("finish");
//电影的输入框对象
var film = document.getElementById("film");
//演员输入框对象
var actor = document.getElementById("actor");
//内容表格对象tbody
var tbody = document.getElementById("tbody");
//模态框对象
var modal = document.getElementById("modal");
close.onclick = function () {
modal.style.display = "none";
};
btn1.onclick = function () {
modal.style.display = "block";
};
finish.onclick = function () {
//电影名称
var filmName = film.value;
//演员名称
var actorName = actor.value;
if (filmName == "" || actorName == "") {
alert("请输入正确的数据!");
return;
}
var arr = [filmName, actorName, "删除"];
var tr = document.createElement("tr");
for (var i = 0; i < 3; i++) {
var td = document.createElement("td");
if (i == 2) {
td.setAttribute("class", "del");
}
td.innerText = arr[i];
tr.appendChild(td);
}
//这块内容是:给新添加的数据绑定删除事件
tr.lastElementChild.onclick = function () {
tbody.removeChild(tr);
};
tbody.appendChild(tr);
modal.style.display = "none";
film.value = "";
//演员名称
actor.value = "";
};
//给原有的数据绑定一个删除的事件。
var dels = document.getElementsByClassName("del");
for (var i = 0; i < dels.length; i++) {
dels[i].onclick = function () {
var trNode = this.parentNode;
tbody.removeChild(trNode);
}
}