DOM 简介
1. DOM 概念
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言的标准编程接口。
它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和 www 文档的风格(目前,HTML 和 XML 文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。
DOM 是一 种基于树的 API 文档,它要求在处理过程中整个文档都表示在存储器中。
总结:W3C 已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构、样式。
2. DOM 树
DOM 又称为文档树模型
(1)文档:一个网页可以称为文档,DOM中使用 document 表示
(2)节点:网页中的所有内容都是节点 (标签、属性、文本、注释等),DOM中用 node 表示
(3)元素:网页中的标签,DOM中使用 element 表示
(4)属性:标签的属性
注:DOM 把文档、节点、元素都看作是对象
3. DOM 经常进行的操作
(1)获取元素
(2)对元素进行操作(设置其属性或调用其方法)
(3)动态创建元素
(4)事件(什么时机做相应的操作)
DOM 获取页面元素
1. 获取页面元素
我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,才进行后续操作。
2. 根据 id 获取元素
(1)方法:调用 document 对象的 getElementById 方法。
(2)参数:字符串类型的 id 的属性值。
(3)返回值:对应 id 名的元素对象。
(4)注意1:由于 id 名具有唯一性,部分浏览器支持直接使用 id 名访问元素,但不是标准方式, 不推荐使用。
(5)注意2:代码执行顺序,如果 js 在 html 结构之前,会导致结构未加载,不能获取对应id的元素
<body>
<p id="para">text</p>
<p id="para">text1</p>
<p id="box">text2</p>
<script>
// 代码书写顺序:js中获取元素时,必须保证元素已经在浏览器中渲染成功
// 所以需要将 js 代码写在 html 结构之后
var para = document.getElementById("para");
console.log(para); // 输出完整的标签 <p id="para">text</p>
console.log(typeof para); // object
// 补充:在控制台打印具体的对象,更好的查看里面的属性和方法
console.dir(para); // p#para 具体的对象
// id 名的唯一性,只会找第一个符合的元素
para.style.background = "pink"; // 只有第一个text变粉色
// 部分浏览器支持直接使用 id 名访问元素也能实现成功,但不推荐直接使用 id 名
// box.style.background = "blue";
</script>
</body>
3. 根据标签名获取元素
(1)方法:调用 document 对象的 getElementsByTagName 方法。(普通元素对象也可调用获取内部的元素)
(2)参数:字符串类型的标签名。
(3)返回值:同名的元素对象组成的集合(以伪数组的形式存储)。
(4)注意1:操作数据时需要按照操作数组的方法进行。
(5)注意2:getElementsByTagName 方法内部获取的元素是动态增加的
<body>
<p>text1</p>
<p>text2</p>
<p>text3</p>
<p>text4</p>
<div>
<p>text5</p>
</div>
<script>
var ps = document.getElementsByTagName("p");
console.log(ps); // HTMLCollection(5) [p, p, p, p, p] html元素组成的集合 伪数组
console.log(ps[0]); // <p style="background: pink;">text1</p> 因为是动态增加的,所以下面添加了背景颜色,这里也会变化
// 遍历:想要依次打印里面的元素对象可以采取遍历的方式
// 得到的元素对象是动态的(若html元素内容变化,js不用变)
for (var i = 0; i < ps.length; i++) {
console.log(ps[i]); // 输出每一项 按照开始标签出现顺序依次排列
}
// 操作时按照操作数组的方法进行
ps[0].style.background = "pink";
// 若页面中只有一个 p,返回的也是伪数组的形式 HTMLCollection [p]
// 若页面中没有 p,返回的是空的伪数组的形式 HTMLCollection []
</script>
</body>
<script>
// 提前获取元素
var divs = document.getElementsByTagName("div");
console.log(divs); // HTMLCollection [] 显示的是空的伪数组 但是后面有添加4个div,因为动态增加,所以里面有4个div
</script>
<!-- body中的代码 -->
<div>text1</div>
<div>text2</div>
<div>text3</div>
<div>
<p>text5</p>
</div>
4. 元素对象内部获取标签元素
(1)获取的元素对象内部,本身也可以调用根据标签获取元素方法,例如 div 元素对象也可以调用 getElementsByTagName 方法。
(2)目的:缩小选择元素的范围,类似 css 中的后代选择器
(3)父元素必须是单个对象(必须指明是哪一个元素对象),获取时不包括父元素自己。
<body>
<div id="box1">
<p>text1</p>
<p>text2</p>
</div>
<script>
// var ps1 = document.getElementById("box1").getElementsByTagName("p");
// 习惯将连续调用方式拆开书写 ***
var box1 = document.getElementById("box1");
var ps1 = box1.getElementsByTagName("p");
console.log(ps1); // HTMLCollection(2) [p, p]
// 或者是
var div = document.getElementsByTagName("div");
var ps1 = div[0].getElementsByTagName("p"); // 通过div[0]拿到第一个div
console.log(ps1); // HTMLCollection(2) [p, p]
</script>
</body>
5. 根据 name 获取元素
(1)方法:调用 document 对象的 getElementsByName 方法。
(2)参数:字符串类型的 name 属性值。
(3)返回值:name 属性值相同的元素对象组成的集合(伪数组形式)。
(4)不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素
<body>
<form>
<input type="radio" name="age" />0~10<br />
<input type="radio" name="age" />11~20<br />
<input type="radio" name="age" />21~30<br />
</form>
<script>
var ages = document.getElementsByName("age");
console.log(ages); // NodeList(3) [input, input, input]
// NodeList 节点列表集合 类数组
// 方法选中的元素也是动态变化的
</script>
</body>
6. 根据类名获取元素
(1)方法:调用 document 对象的 getElementsByClassName 方法。(普通元素对象也可调用获取内部的元素)
(2)参数:字符串类型的 class 属性值。
(3)返回值:class 属性值相同的元素对象组成的动态集合(伪数组)。
(4)此方法内部获取的元素是动态增加的
(5)浏览器兼容问题:不支持 IE8 及以下的浏览器
<body>
<div id="box1">
<p class="para">1</p>
<p class="para">2</p>
</div>
<script>
var paras = document.getElementsByClassName("para");
console.log(paras); // HTMLCollection(2) [p.para, p.para]
// 或者是
var box1 = document.getElementById("box1");
var paras = box1.getElementsByClassName("para");
console.log(paras); // HTMLCollection(2) [p.para, p.para]
</script>
</body>
7. 根据选择器获取元素
(1)方法1:调用 document 对象的 querySelector 方法,通过 css 中的选择器去选取第一个符合条件的标签元素。
(2)方法2:调用 document 对象的 querySelectorAll 方法,通过 css 中的选择器去选取所有符合条件的标签元素集合(伪数组)。
(3)参数:字符串类型的 css 中的选择器。 (例如:.box / #nav)
(4)浏览器兼容问题:不支持 IE8
(5)需要将 js 代码写在 html 结构之后;不会动态增加
<body>
<div id="box1">
<p>1</p>
<p class="para">2</p>
<p class="para">3</p>
</div>
<script>
var para = document.querySelector("#box1 .para");
console.log(para); // <p class="para">2</p>
var paras = document.querySelectorAll("#box1 .para");
console.log(paras); // NodeList(2) [p.para, p.para]
</script>
</body>
8. 获取特殊元素(body、html)
(1)获取 body 元素
document.body
(2)获取 html 元素
document.documentElement
9. 总结
(1)掌握,没有兼容问题
- getElementById()
- getElementsByTagName()
(2)了解
- getElementsByName()
- getElementsByClassName()
- querySelector()
- querySelectorAll()
DOM 事件基本应用
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为,网页中的每个元素都可以产生某些可以触发 JavaScript 的事件。
1. 事件
(1)事件:在什么时候做什么事
(2)执行机制:触发–响应机制 (例:轮播图、下拉菜单)
(3)绑定事件(注册事件)三要素:
- 事件源:给谁绑定事件
- 事件类型:绑定什么类型的事件 (例:click 单击 )
- 事件函数:事件发生后执行什么内容,写在函数内部(采用函数赋值形式)
2. 事件监听
JavaScript 解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要 触发对应的绑定事件,会立刻执行事件函数。
3. 常用事件监听方法
(1)绑定 HTML 元素属性。
<input type="button" id="btn" value="点我有惊喜" onclick="alert('点我做什么')" />
(2)绑定 DOM 对象属性。
<body>
<input type="button" id="btn" value="点我有惊喜" />
<script>
// 获取元素
var btn = document.getElementById("btn");
// 添加绑定事件
btn.onclick = function () {
// 定义的是事件被触发后要做的事
alert("惊喜");
};
</script>
</body>
4. 常用的鼠标事件类型
- onclick → 鼠标左键单击触发
- ondbclick → 鼠标左键双击触发
- onmousedown → 鼠标按键按下触发
- onmouseup → 鼠标按键放开时触发
- onmousemove → 鼠标在元素上移动触发
- onmouseover → 鼠标移动到元素上触发
- onmouseout → 鼠标移出元素边界触发
- onfocus → 获得鼠标焦点触发
- onblur → 失去鼠标焦点触发
DOM 元素属性操作
1. 非表单元素的属性
例如:href、title、id、src 等。
(1)调用方式:元素对象打点调用属性名,例如 obj.href。
(2)注意:部分的属性名跟关键字和保留字冲突,会更换写法。
- class → className
- for → htmlFor
- rowspan → rowSpan
(3)属性赋值:给元素属性赋值,等号右侧的赋值都是字符串格式。
<body>
<a href="http://www.baidu.com" id="link">跳转</a>
<img src="images/a.jpg" class="pic" id="pic" />
<script>
var link = document.getElementById("link");
var pic = document.getElementById("pic");
console.log(link.href); // http://www.baidu.com
console.log(link.id); // link id属性值不可以随意更改
console.log(pic.src); // img 的绝对路径
console.log(pic.className); // pic 注意获取class采用的是className
pic.src = "images/b.jpg"; // 赋值时,等号右侧是字符串格式
</script>
</body>
案例:点击切换图片
<body>
<input type="button" value="点击" id="btn" /><br />
<img src="images/a.jpg" id="pic" width="400" height="300" />
<script>
var btn = document.getElementById("btn");
var pic = document.getElementById("pic");
// 通过一个变量作为判断条件,变量值为 1,认为加载的是 a图片,如果是 2,认为加载的是 b 图片
var num = 1;
btn.onclick = function () {
if (num === 1) {
pic.src = "images/b.jpg";
// 数字要对应发生变化
num = 2;
} else {
pic.src = "images/a.jpg";
num = 1;
}
};
</script>
</body>
案例:点击按钮显示隐藏元素
/* CSS 代码 */
* {
margin: 0;
padding: 0;
}
div {
width: 200px;
height: 200px;
background-color: pink;
}
.hide {
display: none;
}
.show {
display: block;
}
<!-- html 和 JavaScript 代码 -->
<body>
<input type="button" value="点击隐藏" id="button" />
<div id="box"></div>
<script>
var btn = document.getElementById("button");
var box = document.getElementById("box");
// 通常把样式代码写到 css 中,然后在 js 中调用样式类名进行切换
btn.onclick = function () {
// 根据 btn 的 value 值进行条件判断
// 在事件函数内部有一个 this,指向事件源
if (this.value === "点击隐藏") {
box.className = "hide";
this.value = "点击显示";
} else {
box.className = "show";
this.value = "点击隐藏";
}
};
</script>
</body>
补充:不同函数内部 this 的指向
(1)普通函数 → 指向 window 对象
(2)构造函数 → 指向生成的实例对象
(3)对象的方法 → 指向对象本身
(4)事件函数 → 指向事件源
案例:人物画廊
<!-- html 代码 -->
<h2>人物画廊</h2>
<div id="imagegallery">
<a href="images/1.jpg" title="人物A">
<img src="images/1-small.jpg" width="100px" alt="人物1" />
</a>
<a href="images/2.jpg" title="人物B">
<img src="images/2-small.jpg" width="100px" alt="人物2" />
</a>
<a href="images/3.jpg" title="人物C">
<img src="images/3-small.jpg" width="100px" alt="人物3" />
</a>
<a href="images/4.jpg" title="人物D">
<img src="images/4-small.jpg" width="100px" alt="人物4" />
</a>
</div>
<div style="clear: both"></div>
<img id="image" src="images/placeholder.png" width="450px" />
<p id="des">选择一个图片</p>
/* CSS 代码 */
body {
background-color: #ccc;
margin: 1em 10%;
font-family: "Helvetica", "Arial", serif;
color: #333;
}
h2 {
background-color: transparent;
color: #333;
}
a {
background-color: transparent;
color: #c60;
font-weight: bold;
text-decoration: none;
}
#imagegallery a {
display: inline;
padding: 0px;
margin-right: 10px;
}
#imagegallery a img {
border: 0;
}
// js 代码
var imagegallery = document.getElementById("imagegallery");
var links = imagegallery.getElementsByTagName("a");
var image = document.getElementById("image");
var des = document.getElementById("des");
// 遍历数组 添加点击事件
for (var i = 0; i < links.length; i++) {
links[i].onclick = function () {
// this 关键字指代的是触发事件的真正事件源,此处写 links[i] 会出错
image.src = this.href;
des.innerText = this.title;
// 取消 a 标签的默认跳转效果
return false;
};
}
// for 循环内部添加的绑定事件,在触发时,所有的批量添加事件已经成功,触发事件时都是在循环结束之后
// 批量绑定的事件的事件函数内部如果有 i 变量,要注意,函数执行时已经是在循环结束后
// 循环内部定义的变量是一个全局变量,在循环后执行的 i 变量的值是 i 跳出循环时的值
// 若在循环内写 image.src = links[i].href; 此时的 i 的值是4,所以会出错
2. 获取标签内部内容的属性
(1)innerHTML属性,在获取标签内部内容时,如果包含标签,获取的内容会包含标签,获取的内容包括空白换行等。
(2)innerText属性,在获取标签内部内容时,如果包含标签,获取的内容会过滤标签,获取的内容会去掉换行和缩进等空白。
3. 更改标签内容
(1)innerHTML 设置属性值,有标签的字符串,会按照 HTML 语法中的标签加载。 (在设置有内部子标签结构时使用)
(2)innerText 设置属性值,有标签的字符串,会按照普通的字符加载。(在设置纯字符串时使用)
<div id="box">
这是一个 div 标签
<span>这是一个 span 标签</span>
</div>
<script>
var box = document.getElementById("box");
// 调用标签内部内容
console.log(box.innerHTML);
/*
这是一个 div 标签
<span>这是一个 span 标签</span>
*/
console.log(box.innerText); // 这是一个 div 标签 这是一个 span 标签
// 设置标签内部的内容
// box.innerHTML = "<h2>Hello JS</h2>"; // 显示二级标题 Hello JS
box.innerText = "<h2>Hello JS</h2>"; // 显示 <h2>Hello JS</h2>
</script>
总结:innerText 不识别 html 标签,非标准,去除空格和换行。
总结:innerHTML 识别 html 标签,W3C标准,保留空格和换行。
4. 表单元素属性
(1)value → 用于大部分表单元素的内容获取(option除外)
(2)type → 可以获取input标签的类型(输入框或复选框等)
(3)disabled → 禁用属性
(4)checked → 复选框选中属性
(5)selected →下拉菜单选中属性
* 注意:在 DOM 中元素对象的属性值只有一个时,会被转成布尔值显示。 例如:txt.disabled = true;
<body>
<input type="button" value="按钮" id="btn" /><br />
<input type="text" id="txt" />
<select id="list">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
<script>
var btn = document.getElementById("btn");
var txt = document.getElementById("txt");
var list = document.getElementById("list");
var opts = list.getElementsByTagName("option");
console.log(btn.value); // 按钮
console.log(txt.type); // text
console.log(opts[0].innerHTML); // 北京
console.log(opts[0].value); // beijing
console.log(list.disabled); // false
btn.value = "点击";
txt.value = "请输入内容";
// 表单元素特有的一些属性,属性名和属性值是一致的,用 true / false 表示
btn.disabled = true; // 按钮被禁用
</script>
</body>
案例:随机设置下拉菜单中的选中项
<body>
<input type="button" value="选择" id="btn" /><br />
<select id="food">
<option>烤肉</option>
<option>拉面</option>
<option>小龙虾</option>
<option>火锅</option>
<option>麻辣烫</option>
</select>
<script>
var btn = document.getElementById("btn");
var food = document.getElementById("food");
var opts = food.getElementsByTagName("option");
btn.onclick = function () {
// 每次点击需要获取一个 opts 数组的随即下标
// Math.random() [0,1)
// Math.random()*5 [0,5) 向下取整 得到 [0,4]
var n = Math.floor(Math.random() * opts.length);
opts[n].selected = true;
};
</script>
</body>
案例:搜索文本框
<!-- html 与 js 代码 -->
<body>
<input type="text" class="gray" value="请输入搜索关键字" id="txtSearch" />
<input type="button" value="搜索" id="btnSearch" /> <script>
var txtSearch = document.getElementById("txtSearch");
// 获得焦点 onfocus 时,如果文本框内容是默认内容,需要清空文字,让文字加载黑色
txtSearch.onfocus = function () {
if (this.value === "请输入搜索关键字") {
this.value = "";
this.className = "black";
}
};
// 失去焦点 onblur 时,如果文本框内容为空,需要改为默认提示内容,让文字颜色变为灰色
txtSearch.onblur = function () {
// 如果用户输入的内容与默认提示文本相同,失去焦点时,文字颜色也要变成灰色
if (this.value === "" || this.value === "请输入搜索关键字") {
this.value = "请输入搜索关键字";
this.className = "gray";
}
};
</script>
</body>
/* CSS 代码 */
.gray {
color: gray;
}
.black {
color: black;
}
案例:全选与反选
<!-- html 和 js 代码 -->
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="all" />
</th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="tb">
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPhone8</td>
<td>8000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Pro</td>
<td>5000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Air</td>
<td>2000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Apple Watch</td>
<td>2000</td>
</tr>
</tbody>
</table>
<input type="button" value=" 反 选 " id="btn" />
</div>
<script>
var all = document.getElementById("all");
var tb = document.getElementById("tb");
var tb_inputs = tb.getElementsByTagName("input");
var btn = document.getElementById("btn");
// 1.全选:让子选项的选择效果始终与全选保持一致
all.onclick = function () {
// 遍历所有的子选项
for (var i = 0; i < tb_inputs.length; i++) {
tb_inputs[i].checked = all.checked;
}
};
// 2.单独选择子选项过程
// 给每一次点击任何一个子选项进行判断
for (var i = 0; i < tb_inputs.length; i++) {
tb_inputs[i].onclick = function () {
// 需要判断所有的子选项是否都是选中的状态,如果都选中,让全选被选中,如果有的没有被选中,让全选取消选择
allChecked();
};
}
// 3.反选
btn.onclick = function () {
// 让所有子选项与之前的状态相反
for (var i = 0; i < tb_inputs.length; i++) {
tb_inputs[i].checked = !tb_inputs[i].checked;
}
// 控制全选效果,也需要进行取反
allChecked();
};
// 定义一个 all 是否被选中的函数
function allChecked() {
// 使用一个中间过渡变量,初始认为所有的子选项都是被选中的
var isAllChecked = true;
// 遍历所有子选项,进行判断
for (var j = 0; j < tb_inputs.length; j++) {
// 一旦有一个是没有被选择的,让变量变为 false
if (tb_inputs[j].checked === false) {
isAllChecked = false;
// 只要走到这里,说明肯定不是全选,不需要往下执行循环
break;
}
}
// 如果循环内部条件永远不成立,说明所有子选项都是被选中,isAllChecked 的值没有发生变化,还是 true
// 给 all 元素设置 checked 属性
all.checked = isAllChecked;
}
</script>
</body>
/* CSS 代码 */
* {
margin: 0;
padding: 0;
}
.wrap {
width: 300px;
margin: 100px auto 0;
}
table {
width: 300px;
border: 1px solid #c0c0c0;
border-collapse: collapse;
border-spacing: 0;
}
th,
td {
padding: 10px;
border: 1px solid #d0d0d0;
color: #404060;
}
th {
background-color: #09c;
color: #fff;
font: bold 16px "微软雅黑";
}
td {
font: 14px "微软雅黑";
}
tbody tr {
background-color: #f0f0f0;
}
tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
5. 自定义属性操作
(1)getAttribute(name) → 获取标签行内属性
(2)setAttribute(name,value) → 设置标签行内属性
(3)removeAttribute(name) → 移除标签行内属性
(4)与element.属性的区别: 上述三个方法用于获取任意的行内属性,包括自定义的属性。
(5)注意:
- 以上方法的参数都是字符串格式。
- setAttribute 中传的参数 name 不需要进行属性名的修改,因为参数是字符串格式,和标识符不会有冲突。(例如:class 写作 class 就好,不用写成 className)
<body>
<div id="box" age="18" sex="male">小明</div>
<script>
var box = document.getElementById("box");
// 获取元素自有属性
console.log(box.id); // box
// 获取自定义属性,自定义属性不能直接打点调用
console.log(box.getAttribute("age")); // 18
// 此方法也可以调用自有属性
console.log(box.getAttribute("id")); // box
// 设置属性,添加新的自定义属性或自有属性
box.setAttribute("age", "20");
box.setAttribute("city", "beijing");
// 传的参数不需要进行属性名的修改,因为参数是字符串格式,和标识符不会有冲突
box.setAttribute("class", "demo");
// 移除属性
box.removeAttribute("age");
box.removeAttribute("class");
</script>
</body>
补充:可以定义一个获取元素的函数,之后调用即可
function my$(id){
return document.getElementById(id);
}
// 存入变量中的原因:只调用一次函数,这个对象就可以反复使用
var btn = my$("btn"); // 获取 id 名为 btn 的元素
6. style 样式属性操作
element.style
(样式修改比较少或功能简单时使用)
(1)使用 style 属性方式设置的样式显示在标签行内。
(2)element.style 属性的值,是所有行内样式组成的一个样式对象。 (外联式和内嵌式获取不到)
(3)样式对象可以继续点语法调用或更改 css 的行内样式属性,例如 width、height 等属性。
(4)注意1:类似 background-color 这种复合属性的单一属性写法,是由多个单词组成的,要修改为驼峰命名方式书写 backgroundColor。
(5)注意2:通过样式属性设置宽高、位置的属性类型是字符串,需要加上 px 等单位
<body>
<div id="box" style="width: 100px" class="bg">文字</div>
<script>
var box = my$("box");
// 元素对象的 style 属性的值是一个行内样式组成的对象,对象内部封装了所有的行内的样式属性及属性值
console.log(box.style);
// 元素的 style 属性对象可以继续打点调用,获取或设置相关的行内样式属性
console.log(box.style.width); // 100px
console.log(box.style.backgroundColor); // 输出为空
box.style.width = "300px";
</script>
</body>
7. className 样式属性操作
element.className
(样式修改比较多或功能复杂时使用)
(1)修改元素的 className 属性相当于直接修改标签的类名。
(2)如果需要修改多条 css 样式,可以提前将修改后的样式设置到一个类选择器中,后续通过 修改类名的方式,批量修改 css 样式
test.onclick = function () {
this.className = "first change";
// 多类名选择器:保留原先类名first,加上修改后的类名change(样式写在CSS代码中)
};
注:className 会直接更改元素的类名,会覆盖原先的类名,若要保留,则使用多类名选择器。
案例:显示隐藏二维码
<body>
<div class="box" id="box">
<div class="erweima hide" id="er">
<img src="images/456.png" alt="" />
</div>
</div>
<script>
var box = document.getElementById("box");
var er = document.getElementById("er");
// 鼠标移上事件
box.onmouseover = function () {
// er.className = "erweima show";
er.className = er.className.replace("hide", "show");
};
// 鼠标离开事件
box.onmouseout = function () {
// er.className = "erweima hide";
er.className = er.className.replace("show", "hide");
};
</script>
</body>
/* CSS 代码 */
.box {
position: fixed;
right: 10px;
top: 40%;
width: 50px;
height: 50px;
background: url(images/bgs.png) no-repeat -159px -51px;
}
.erweima {
position: absolute;
top: 0;
left: -150px;
}
.hide {
display: none;
}
.show {
display: block;
}
8. 排他思想(算法)
若有同一组元素,我们想要某一个元素实现某种样式,其他不需要,则用到循环的排他思想算法
- 所有元素全部清除样式
- 给当前元素设置样式
- 注意顺序不能颠倒,首先 for 循环排除所有,再设置自己
案例:文本框高亮显示
// js 代码
// 获取所有input文本框
var txts = document.getElementsByTagName("input");
for (var i = 0; i < txts.length; i++) {
// 排他思想:1.排除其他 2.保留自己
txts[i].onfocus = function () {
// 排除其他的方法:将所有的项包含自己都设置为默认样式
// 遍历数组,让所有的样式恢复默认
for (var j = 0; j < txts.length; j++) {
txts[j].style.backgroundColor = "";
}
// 保留自己的特殊样式
this.style.backgroundColor = "pink";
};
}
案例:开关灯案例
<!-- 第一种方法 -->
<body>
<input type="button" value="关灯" id="btn" />
<script>
var btn = document.getElementById("btn");
// 定义一个判断变量,true 表示开灯状态,false 表示关灯状态
var flag = true;
btn.onclick = function () {
if (flag) {
document.body.style.backgroundColor = "#000";
this.value = "开灯";
flag = false;
} else {
document.body.style.backgroundColor = "#fff";
this.value = "关灯";
flag = true;
}
};
</script>
</body>
<!-- 第二种方法 -->
<body>
<input type="button" value="关灯" id="btn" />
<script>
var btn = document.getElementById("btn");
btn.onclick = function () {
if (this.value === "关灯") {
document.body.style.backgroundColor = "#000";
this.value = "开灯";
} else {
document.body.style.backgroundColor = "#fff";
this.value = "关灯";
}
};
</script>
</body>
案例:表格隔行变色和高亮显示
表格 table 分为 thead 和 tbody,变色只有 tbody ,第一行 thead 不参与,所以只有 tbody 里的行 tr 变化。
// 获取 tbody
var tb = document.getElementById("tb");
// 获取 tbody 里的所有的 tr
var trs = tb.getElementsByTagName("tr");
// 1.隔行变色
for (var i = 0; i < trs.length; i++) {
// 下标为偶数的行显示粉色
// 下标为奇数的行显示灰色
if (i % 2 == 0) {
trs[i].style.backgroundColor = "pink";
} else {
trs[i].style.backgroundColor = "lightgray";
}
// 全局变量
var bgc;
// 鼠标移上高亮显示
trs[i].onmouseover = function () {
// 定义变量记录 tr 原来的颜色
bgc = this.style.backgroundColor;
this.style.backgroundColor = "skyblue";
};
// 鼠标离开恢复默认
trs[i].onmouseout = function () {
this.style.backgroundColor = bgc;
};
}
案例:tab 选项卡切换
<body>
<div class="box">
<div class="hd" id="hd">
<span class="current">体育</span>
<span>娱乐</span>
<span>新闻</span>
<span>综合</span>
</div>
<div class="bd" id="bd">
<div class="current">我是体育模块</div>
<div>我是娱乐模块</div>
<div>我是新闻模块</div>
<div>我是综合模块</div>
</div>
</div>
<script>
var hd = document.getElementById("hd");
var spans = hd.getElementsByTagName("span");
var bd = document.getElementById("bd");
var divs = bd.getElementsByTagName("div");
// 鼠标移上某个 span ,让它添加一个类名,其他的失去类名
for (var i = 0; i < spans.length; i++) {
// 给每个span添加一个新属性,用来记录自己在数组中的下标
// spans[i].setAttribute("index", i);
spans[i].index = i;
spans[i].onmouseover = function () {
// 排他思想
for (var j = 0; j < spans.length; j++) {
spans[j].className = "";
// 由于 divs 中数据个数与 spans 一样,所以可以在同一个遍历循环中,进行排他操作
divs[j].className = "";
}
// 保留自己
this.className = "current";
// 对应控制思想:有两组数据中存储了相同个数的元素对象,一组对象的变化,会引起另外一组的变化
// 实现方法:找两个数据中的共同点,两个数组中元素对象的下标是一样的
// 对应控制中也会涉及到排他操作
// 保留div自己的类名
// var index = this.getAttribute("index");
// divs[index].className = "current";
divs[this.index].className = "current";
};
}
</script>
</body>
/* css 代码 */
* {
margin: 0;
padding: 0;
}
.box {
width: 400px;
height: 300px;
border: 1px solid #ccc;
margin: 100px auto;
}
.box .hd {
height: 45px;
}
.hd span {
display: inline-block;
width: 90px;
height: 100%;
background-color: pink;
line-height: 45px;
text-align: center;
}
.hd span.current {
background-color: skyblue;
}
.bd div {
display: none;
height: 255px;
background-color: skyblue;
}
.bd div.current {
display: block;
}
9. H5 自定义属性
目的:为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中
因为有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性,所以H5新增了自定义属性
(1)设置 H5 自定义属性
H5 规定自定义属性 data- 开头作为属性名并且赋值
-
<div data-index="1"></div>
-
或者在 JS 中设置
div.setAttribute("data-index",2);
(2)获取 H5 自定义属性
- 兼容性获取:`element.getAttribute(“data-index”)(兼容性好)
- H5 新增:
element.dataset.index
/element.dataset["index"]
(IE11 才开始支持)(只能获取 data- 开头,dataset 是一个集合,里面存放了所有以 data 开头的自定义属性 )
注:如果自定义属性里面有多个 - 连接的单词,获取时采取驼峰命名法
<div data-list-name="andy"></div>
<script>
console.log(div.getAttribute("data-list-name"));
console.log(div.dataset.listName);
console.log(div.dataset["listName"]);
</script>