笔记来源:拉勾教育 - 大前端就业集训营
文章内容:学习过程中的笔记、感悟、和经验
DOM
Web API简介
API是一些预先设置好的函数,目的是提供应用程序和开发人员基于某个软件或者硬件访问一组例程的能力,而又无需访问源码,不需要理解其内部的运行机制
任何语言都有自己的API
API的特征:输入和输出(I / O):例如:var max = Math.max(2,3,4);
API的使用方法:例如:console.log('abc')
概念
- 浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)
- 这里所指的Web API是浏览器提供的API(方法),后面会有其他含义
- 参考文档:developer.mozilla.org/zh-CN/docs/…
js的组成
-
ECMAScript:定义js的语法规范
js的核心,是一套标准,定义语言标准而与具体实现无关
-
BOM:浏览器对象模型
一套操作浏览器功能的API,可以操作浏览器窗口,例如:弹出框、页面跳转、获取分辨率等
-
DOM:文档对象模型
一套操作页面元素的API,DOM可以吧整个html结构看作一个文档树,通过DOM提供的API可以对树上的节点进行操作
DOM概念
文档对象模型,是W3C组织推荐的处理可扩展标记语言的标准编程接口,是一种和平台、语言无关的程序接口(API),可以动态访问程序和脚本,更新内容、结构、文档风格。可以进一步处理文档,并可以将处理的结构添加到页面中,是一种基于树的API文档,要求在处理过程中整个文档都表示在存储器中(所有文档都要运行在内存中)
DOM树
- 文档(Document):一个网页可以称为一个文档
- 节点:网页中所有的内容都是节点(标签、属性、文本、注释等)
- 元素(element):网页中的标签
- 属性:标签的属性
DOM树操作
获取元素、对元素操作(设置属性、调用方法)、动态创建元素、事件
DOM使用
获取页面元素
我们想要对页面上某个部分进行操作(显隐、动画),需要先获取到这个元素才能进行后续操作
注意:
- 要想获取元素,必须保证浏览器中这个元素已经正常加载,所以可以吧js代码放到html结构后面
- 使用
console.dir()可以在控制台打印整个对象,而不是输出对象
根据Id获取元素
**调用document上面的getElementByid()方法 **
- 功能:通过元素的id名获取这个元素
- 参数:字符串类型的id属性值
- 返回:对应id名的元素对象
//根据ID获取元素,并赋值给变量
var x = document.getElementById("one");
//输出变量
console.log(x);
//检验变量数据类型
console.log(typeof x);
//使用console.dir打印整个对象,可以打印对象的属性、方法等等
console.dir(x);
//甚至我们可以在这里修改相应的属性值和调用方法
// 修改style属性
x.style.background = 'pink';
//可以直接使用id名访问元素,但这种方法不推荐
tow.style.background = 'skyblue';
注意事项:
- 由于id具有唯一性,部分浏览器支持直接使用id名访问元素,但这不属于官方推荐的标准方式,不建议使用
- 代码执行顺序:如果js写在html结构之前获取元素容易出现问题,所以我们需要把获取元素的操作放在htm结构之后
- 如果一个结构中存在两个同名ID,js使用此方法只能获取第一个同名id元素,这也体现了js的严格性
根据标签名获取元素
**调用document上面的getElementsByTagName()方法 ** TagName(标签名)
- 功能:获取执行标签名的元素
- 参数:字符串类型的标签名
- 返回:一个包含所有指定标签名的元素的数组
<script>
//在结构之前获取元素,按照逻辑来说应该获取不到
var divs = document.getElementsByTagName('div')
//实际打印出来确实获取不到,但是点开可以发现,下面的三个div全部都获取到了
console.log(divs);
</script>
<div>lalallal</div>
<div>lalallal</div>
<div>
<!-- 不管层级如歌,先出现的标签排在前面,后出现的标签排在后面 -->
<p>我是嵌套</p>
</div>
<p class="me1">1</p>
<p class="me2">2</p>
<p class="me3">3</p>
<p class="me4">4</p>
<p class="me4">5</p>
<p class="me6">6</p>
<script>
//再次打印一下三个元素都获取到了
console.log(divs);
//根据ID获取元素,并赋值给变量
var x = document.getElementsByTagName("p");
//输出变量
console.log(x); //返回的是一个类似于数组的伪造数组
//可以使用数组遍历方法访问内部元素
for (let i = 0; i < x.length; i++) {
console.log(x[i]);
}
//想要操作数组中的元素必须按照数组的方式来进行
x[0].style.background = 'pink';
</script>
注意事项:
- 使用数据要使用数组的方式来实现
- 此方法获取元素是可以动态增加的(如果我们在结构前获取数据,按照js逻辑来说是无法获取元素的,但是真实情况是虽然表面上看获取不到,但是实际上后期等结构加载后会将加载的元素添加进去)
- 类似css的标签选择器,不管标签是否嵌套都会被获取,获取顺序按照开始标签出现顺序排列
在对象再次获取元素
可以直接打点再次调用getElementsByTagName()方法 ,类似于css的后代选择器,可以缩小范围
<div>
<p class="p1"></p>
<p class="p2"></p>
<p class="p3"></p>
<p class="p4"></p>
</div>
<script>
//获取div,这里使用id获取也可以
var divs = document.getElementsByTagName('div');
//进一步获取div内部的p元素,注意要使用数组方法,相当于缩小了范围
var ps = divs[0].getElementsByTagName('p');
//输出ps
console.log(ps);
</script>
根据name属性获取元素
**调用document上面的getElementsByName()方法 **
- 功能:获取指定name属性值的元素,并返回数组
- 参数:字符串类型的name属性值
- 返回值:同那么属性值的元素所组成的数组
注意:工作中不建议使用:欧朋、ie浏览器中会有兼容性问题,会把同id的元素选中
<form action="">
<input type="text" name="me">wo<br />
<input type="text" name="me">wo<br />
<input type="text" name="me">wo<br />
</form>
<p id="me">我的id是me</p>
<script>
//获取name属性为me的元素
var me = document.getElementsByName('me');
//输出一下。发现在ie中会把p标签也获取出来
console.log(me);
//这里发现输出的类型为NodeList,可能会出现非元素节点
</script>
选中的元素是动态的变化的,和标签名选择一样
根据class属性获取元素
调用document对象的getElementByClassName()方法
- 功能:获取指定class类名的元素
- 参数:字符串类名
- 返回:所有同类名的元素数组
注意:不兼容IE8级以下浏览器,
<div id="box1">
<p class="me">我要选中</p>
<p class="me">我要选中</p>
<p>我不要选中</p>
</div>
<div id="box2">
<p class="me">我要选中</p>
<p class="me">我要选中</p>
<p>我不要选中</p>
</div>
<script>
//获取id属性为me的元素
var div = document.getElementById('box1'),
//使用class属性进一步缩小范围获取元素
me = div.getElementsByClassName('me');
//打印输出变量
console.log(me);
</script>
注意事项:
- 内部元素和之前一样同样可以动态添加
- 可以使用内部在进行获取元素缩小范围
根据选择器获取元素
调用document上的querySelector(选中符合条件的第一个元素)方法或者的querySelectorAll(选中所有符合条件的元素)方法
- 功能:通过css中选择器选择
- 参数:字符串类型的css选择器
- 返回;类数组
注意:IE8级以下不兼容
<div id="box1">
<p class="me">我要选中</p>
<p class="me">我要选中</p>
<p>我不要选中</p>
</div>
<div id="box2">
<p class="me">我要选中</p>
<p class="me">我要选中</p>
<p>我不要选中</p>
</div>
<script>
//使用选择器选择,选择第一个div下面的第一个class类名为me的元素
var me = document.querySelector('div .me');
console.log(me);
//选择所有div下的class类名为me的元素
var me2 = document.querySelectorAll('div .me');
console.log(me2);
</script>
注意事项:
- 只能写在加载完成之后
querySelector结果可以直接使用,不是数组
总结
掌握,没有兼容问题
getEIementById、 getEIementsByTagName
了解
getEIementsByName、 getEIementsByCIassName、querySelector、querySelectorAll
事件
- 在什么时候做什么事
- 执行机制:触发----响应
- 绑定时间三要素:
- 事件源:绑定时间的元素
- 事件类型:绑定什么类型的事件(点击、鼠标移入等)
- 事件函数:事件发生后执行什么内容(代码),写在事件函数内部
事件绑定(监听)方法
- 直接绑定在HTML元素属性上
- 绑定在DOM对象上
<!-- 直接绑定在HTML结构上 -->
<input type="button" value="直接绑定在元素上" onclick="alert('这就是')">
<!-- 绑定在DOM对象上面 -->
<input type="button" id="me" value="绑定在dom对象上">
<script>
//获取对象
var me = document.getElementById('me');
//绑定事件
me.onclick = function () {
alert('点我干嘛');
}
</script>
事件监听:当给一个元素绑定了事件后,解析器会给这个元素添加一个监听,只要出发对应的绑定事件,就会立即执行这个函数
常见鼠标事件类型
| 事件类型 | 说明 |
|---|---|
| onclick | 鼠标单击 |
| ondblclick | 鼠标双击 |
| onmousedown | 鼠标按下 |
| onmouseUp | 鼠标放开 |
| onmousemove | 鼠标在元素上移动时 |
| onmouseover | 鼠标移到元素上 |
| onmouseout | 鼠标移出元素边界 |
非表单元素属性
例如:href、title、id、src等,注意id属性是只读的,只读取不要更改
- 调用方式:元素对象打点调用,例如
obj.href - 属性赋值:给元素属性赋值,等号右侧为字符串类型。例如
ob j.id = 'one' - 注意:有部分属性名和保留字会发生冲突,会换一个写法,例如:
class---className、for---htmlFor、rowspan---rowSpan
<img id="img" src="地址" alt="">
<a id="a" href="地址">点我</a>
<script>
//获取对象
var img = document.getElementById('img');
var a = document.getElementById('a');
//绑定事件
img.onclick = function () {
//给元素属性重新赋值(值必须是字符串类型)
img.src ='新地址';
a.href = '新地址';
};
</script>
案例:点击按钮切换图片
<!-- 需求:点击按钮切换图片 -->
<!-- 添加按钮 -->
<input id="buttom" type="button" value="点击我切换">
<!-- 添加图片 -->
<img id="img" src="./images/a.jpg" alt="">
<script>
//获取元素
var buttom = document.getElementById('buttom'),
img = document.getElementById('img'),
// 注意:如果使用img.src获取到的是一个绝对路径,所以我们使用一个中间变量进行判断,默认值和我们默认的图片相对应
x = 1;
//给按钮绑定事件
buttom.onclick = function () {
//判断x的值,如果x=1就切换图片b,如果是2就切换a,别忘了同时要修改x的值
if (x === 1) {
img.src = './images/b.jpg'
x = 2;
} else {
img.src = './images/a.jpg'
x = 1;
}
}
</script>
案例:点击按钮切换元素的显示和隐藏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
margin: 20px;
background: pink;
}
/* 预先设置好显示元素和隐藏元素的css样式 */
.xs {
display: block;
}
.yc {
display: none;
}
</style>
</head>
<body>
<!-- 需求:点击按钮切换元素的显示和隐藏 -->
<!-- 添加按钮 -->
<input id="button" type="button" value="点击隐藏">
<!-- 添加div -->
<div id="me"></div>
<script>
//获取元素
var button = document.getElementById('button'),
me = document.getElementById('me');
// 添加事件
button.onclick = function () {
// 使用if语句区分不同情况执行不同代码,这里使用修改class值的方法实现
if (button.value == '点击隐藏') {
me.className = 'yc';
button.value = '点击显示';
} else if (button.value == '点击显示') {
me.className = 'xs';
button.value = '点击隐藏';
}
console.log('1111111111')
}
</script>
</body>
</html>
事件函数内部的this
不同函数中的 this 指向
- 普通函数:指向widow对象
- 构造函数:指向生成的实例对象
- 对象的方法:指向对象本身
- 事件函数:指向事件源
button.onclick = function () {
if (button.value == '点击隐藏') {
me.className = 'yc';
// 将button换成this后一样生效,因为此时this指向button
this.value = '点击显示';
} else if (button.value == '点击显示') {
me.className = 'xs';
// 将button换成this后一样生效,因为此时this指向button
this.value = '点击隐藏';
}
}
案例:美女画廊
需求:点击小图显示大图,并在下方显示这张图片的介绍
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 400px;
overflow: hidden;
}
div a {
float: left;
display: block;
width: 25%;
}
div a img {
width: 100%;
}
#big-img {
width: 400px;
}
</style>
</head>
<body>
<!-- //顶部小图片列表 -->
<div class="img-list">
<!-- 列表内部使用a标签内部承载需要的数据 -->
<a href="./images/1.jpg" title="美女1">
<!-- img内部是真实的小图片 -->
<img src="./images/1-small.jpg" alt="">
</a>
<a href="./images/2.jpg" title="美女2">
<img src="./images/2-small.jpg" alt="">
</a>
<a href="./images/3.jpg" title="美女3">
<img src="./images/3-small.jpg" alt="">
</a>
<a href="./images/4.jpg" title="美女4">
<img src="./images/4-small.jpg" alt="">
</a>
</div>
<!-- 中间的大图 -->
<img id="big-img" src="./images/placeholder.png" alt="点击上面显示大图">
<!-- /底部的介绍文字 -->
<p>选择一张图片</p>
<script>
//获取所有需要的元素
var as = document.getElementsByTagName('a'),
bigImg = document.getElementById('big-img'),
shuoming = document.getElementsByTagName('p')[0];
for (var i = 0; i < as.length; i++) {
// 添加事件
as[i].onclick = function () {
//修改大图的地址,这里使用this,可以避免一些问题
bigImg.src = this.href;
//修改介绍的文本呢内容,修改innerText即可
shuoming.innerText = this.title + '----好漂亮啊(色)';
//禁止a标签的自动跳转功能
return false;
};
}
</script>
</body>
</html>
注意:这里使用var关键字创建for循环的变量,但是var关键字定义的变量是全局变量,所以不应该使用as[i]的方式,因为循环过后as[i]还没有生效,只有点击的时候才会生效,这是i已经变成了4,所以会导致图片链接发生错误,而且会导致return false;失效,这里使用this代替更好
获取标签内容的属性
innerHTML:获取全部内容,包括标签、换行、空白区域innerText:获取全部文字,会过滤标签、空白、换行
<body>
<!-- 创建元素div,内部创建p元素 -->
<div>12344
<p>nishishai</p>
</div>
<script>
//获取元素
var dic = document.getElementsByTagName('div')[0];
//输出两种获取方法
console.log(dic.innerHTML); //这里会输出全部内容
console.log(dic.innerText); //这里只输出文字部分
</script>
</body>
更改内容(赋值)
可以使用=进行赋值操作更改元素的内容
- innerHTML:如果有标签的话,会按照html标签进行渲染(赋值结构时使用)
- innerText:有标签的话,也不会渲染,会按照字符进行渲染(一般设置纯字符串时使用)
<body>
<!-- 创建元素div,内部创建p元素 -->
<div></div>
<div></div>
<script>
//获取元素
var div = document.getElementsByTagName('div');
//f分别是用两个方法修改内容
//innerHTML可以看到在里面直接添加了p标签结构
div[0].innerHTML = '<p>我是一个结构</p>'
//可以看到innerText是直接把文本内容添加了进去
div[1].innerText = '<p>我是一个结构</p>'
</script>
</body>
表单元素属性
- value:可以获取大部分的表单内容(option除外,获取使用inner....)
- type:可以获取input标签的类型(按钮、单选框等)
- disabled:禁用属性
- checked:获取复选框选中状态
- selected:获取下拉菜单选中状态
注意:有些属性值和属性名相同的属性(只有一个值)的时候,会被转换为布尔值,例如:text.disabled = true
<body>
<!-- 创建表单元素 -->
<!-- 按钮 -->
<input type="button" value="按钮" id="btn"><br>
<!-- 文本框 -->
<input type="text" id="txt">
<!-- 下拉菜单 -->
<select id="list">
<option value="beijing">北京</option>
<option selected value="shanghai">上海</option>
</select>
<script>
//获取到所有元素
var btn = document.getElementById('btn'),
txt = document.getElementById('txt'),
list = document.getElementById('list'),
opt = document.getElementsByTagName('option');
//获取属性
console.log(btn.value, opt[0].value);
console.log(btn.type, txt.type);
//属性值和属性名相同的,只会输出布尔值
console.log(list.disabled);
console.log(opt[0].selected);
console.log(opt[1].selected);
// 我们可以修改这些值
list.disabled = true;
txt.value = '我更改了';
</script>
</body>
案例:检测用户输入的用户名和密码是否是3-6位和6-8位,不满足条件的高亮显示
<body>
<!-- 创建三个元素 -->
<input type="text" value="123" id="name"><br>
<input type="text" id="password"><br>
<input type="button" value="提交" id="btn">
<script>
//获取需要的元素
var n = document.getElementById('name'),
pw = document.getElementById('password'),
btn = document.getElementById('btn');
// 给提交按钮增加事件
btn.onclick = function () {
//判断用户名和密码的位数,不满足条件将输入框高亮显示(设置class),并且不会提交数据
if (n.value.length < 3 || n.value.length > 6) {
n.className = 'bg';
return;
} else {
n.className = '';
}
if (pw.value.length < 6 || pw.value.length > 8) {
pw.className = 'bg';
return;
} else {
pw.className = '';
}
//条件都满足提交数据
console.log('提交数据');
}
</script>
</body>
案例:随机选择一个晚餐
<body>
<!-- 创建元素 -->
<!-- 选择按钮 -->
<input type="button" value="今晚吃点啥" id="btn"><br>
<!-- 下拉菜单 -->
<select id="food">
<option>烤肉</option>
<option>拉面</option>
<option>麻辣烫</option>
<option>小龙虾</option>
<option>火锅</option>
<option>外卖</option>
<option>你摸摸你的肚子,还吃?</option>
</select>
<script>
///获取元素
var btn = document.getElementById('btn'),
opts = document.getElementById('food').getElementsByTagName('option');
//给按钮添加事件
btn.onclick = function () {
//产生一个随机数--取整--随机数*下拉菜单个数
var x = Math.floor(Math.random() * opts.length);
//使用随机数,将随机的默认设置为true
opts[x].selected = true;
}
</script>
</body>
案例:获取焦点和失去焦点
搜索框点击获取焦点,点击其他地方失去焦点,并且设置默认是是文本,获得焦点提示内容消失,点击其他地方判断用户是否输入内容,如果输入内容保留,没有输入恢复原来样式
焦点事件
- onfocus -- 获取焦点
- onblur -- 失去焦点
<body>
<!-- 创建元素 -->
<!-- 搜索框 -->
<input type="search" id="search" placeholder="请输入搜索关键字">
<!-- 按钮 -->
<input type="button" value="搜索" id="btn">
<script>
// 获取元素
var sou = document.getElementById('search'),
btn = document.getElementById('btn');
//获取焦点事件
sou.onfocus = function () {
//修改默认的提示内容为空
sou.placeholder = '';
//文字颜色修改
sou.className = 'black'
};
//失去焦点事件
sou.onblur = function () {
//判断文本框内容是否为空
if (sou.value === '') {
// 如果是空的,恢复默认的提示文字
sou.placeholder = '请输入搜索关键字';
}
//修改颜色
sou.className = 'gray';
};
</script>
</body>
案例:全选、反选、多选
实现反选、全选和多选的功能
<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'),
checkboxs = document.getElementById('tb').getElementsByTagName('input'),
btn = document.getElementById('btn');
//循环给每个复选框添加触除默认事件以外的其他功能
for (let i = 0; i < checkboxs.length; i++) {
checkboxs[i].onclick = function () {
//调用判断函数,判断是否应该选中all
trueOrFlase();
}
}
//全选事件
all.onclick = function () {
//将所有复选框都变成和all相同
for (let i = 0; i < checkboxs.length; i++) {
checkboxs[i].checked = this.checked;
}
}
//反选事件
btn.onclick = function () {
//循环执行每个复选框的click事件
for (let i = 0; i < checkboxs.length; i++) {
checkboxs[i].click();
}
}
//功能:判断除了all以外的其他复选框是否都选中,有一个没有选中都不会选中all
//参数:数组
function trueOrFlase() {
//循环遍历数组
for (let i = 0; i < checkboxs.length; i++) {
//只要有一个没有选中都不会选中all
if (checkboxs[i].checked === false) {
all.checked = false;
return;
}
}
//如果能走到这里,说明所有复选框都选中了,那么将all也改为选中
all.checked = true;
}
</script>
</body>
自定义属性
getAttribute(name):获取元素的行内属性
setattribute(name, value):更改或者新增行内属性
remove attribute(name):移除某个行内属性
<body>
<!-- 添加了一个自定义属性age -->
<div class="one" id="me" age="19"></div>
<script>
//获取元素
var d = document.getElementById('me');
//读取属性值,自定义和语法属性都能读取
console.log(d.getAttribute('age'));
console.log(d.getAttribute('class')); //甚至可以读取非自定义属性
//设置、添加属性值:有则修改,无则添加
d.setAttribute('age', '99'); //修改age属性
console.log(d.getAttribute('age'));
d.setAttribute('sex', 'nan'); //新增sex属性
console.log(d.getAttribute('sex')); //nan
d.setAttribute('class', 'nan'); //可以修改非自定义属性
console.log(d.getAttribute('class')); //nan
//删除属性
d.removeAttribute('age'); //删除age属性
console.log(d.getAttribute('age')); //null
d.removeAttribute('class'); //删除class属性
console.log(d.getAttribute('class')); //null
</script>
</body>
注意:上述三个方法可以获取任意属性值,包括非自定义的属性
style样式属性
获取元素的行内样式,注意只能获取行内样式,内嵌式和外链式都不可以
属性值是所有行内样式组成的一个样式对象,可以使用对象点语法调用或者修改
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
</style>
<script>
//封装一个获取元素的函数
function hqys(x) {
//返回获取的元素
return document.getElementById(x);
}
</script>
</head>
<body>
<!-- //一个按钮 -->
<input id="btn" type="button" value="点击">
<!-- //一个div -->
<div class="one" id="me" style="width: 100px;height:100px;background-color: pink;"></div>
<script>
//调用函数获取元素
var btn = hqys('btn'),
me = hqys('me');
//给按钮添加点击事件
btn.onclick = function () {
//修改高度、宽度、背景色
me.style.width = '200px';
me.style.height = '200px';
me.style.backgroundColor = 'skyblue';
}
</script>
</body>
注意:
- 类似background-color这种复合写法的单一属性写法,要写成backgroundColor这样的驼峰式
- 通过样式属性设置宽高,属性值要使用字符串,例如`obj.style.width = '150px'
建议:实际工作中如果更改的属性比较少,可以使用直接修改,如果较多可以使用更改class类名的写法
案例:开关灯
BOM里面内置了body,使用document.body调用
<body>
<!-- //一个按钮 -->
<input id="btn" type="button" value="关灯">
<script>
//调用函数获取元素
var btn = hqys('btn');
//方案1中间变量
var isOpen = true;
//给按钮添加点击事件
btn.onclick = function () {
// 方案1, 使用中间变量判断开关灯状态
// if (isOpen) {
// //更改body背景色
// document.body.style.backgroundColor = 'black';
// //修改按钮文字
// this.value = '开灯';
// //修改中间变量
// isOpen = false;
// } else {
// document.body.style.backgroundColor = 'white';
// this.value = '关灯';
// isOpen = true;
// }
//方案2,直接判断按钮文字,根据文字执行代码
if (this.value === '关灯') {
document.body.style.backgroundColor = 'black';
this.value = '开灯';
} else {
document.body.style.backgroundColor = 'white';
this.value = '关灯';
}
}
// 很明显,方案2更加简洁,如果以后工作中可以进行直接判断,可以考虑使用方案2
</script>
</body>
案例:显示隐藏二维码
需求:鼠标移到小图上显示二维码,移出隐藏二维码
可以使用string.replace('旧字符串',‘新字符串’)进行字符串的替换
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
/* 父盒子固定定位,宽高。背景图 */
#box {
position: fixed;
width: 50px;
height: 50px;
right: 0;
top: 200px;
background: url(./images/bgs.png) no-repeat -159px -51px;
}
/* 图片默认隐藏、绝对定位游离在父盒子外边 */
#box img {
position: absolute;
top: 0;
left: -150px;
width: 150px;
}
/* 显示类名 */
.show {
display: block;
}
/* 隐藏类名 */
.hidden {
display: none;
}
</style>
<script>
//封装一个获取元素的函数
function hqys(x) {
//返回获取的元素
return document.getElementById(x);
}
</script>
</head>
<body>
<!-- 一个大盒子,包裹二维码 -->
<div id="box">
<!-- 默认又一个hidden的类名 -->
<img class="img hidden" src="./images/456.png" alt="">
</div>
<script>
//获取元素
var box = hqys('box'),
img = box.getElementsByClassName('img')[0];
//添加鼠标移上事件
box.onmouseover = function () {
//修改替换类名
img.className = img.className.replace('hidden', 'show');
}
//鼠标移出事件
box.onmouseout = function () {
//修改替换类名
img.className = img.className.replace('show', 'hidden');
}
</script>
</body>
案例:高亮显示正在输入的文本框
排他思想:将其他全部排除,只保留自己
应用:当一组元素中只有一个是特殊的,设置的时候可以先把全部都降级为普通,然后再给指定某个元素设置为特殊
<body>
<!-- 一群输入框 -->
<input type="text" name="" id=""><br>
<input type="text" name="" id=""><br>
<input type="text" name="" id=""><br>
<input type="text" name="" id=""><br>
<input type="text" name="" id=""><br>
<input type="text" name="" id=""><br>
<button>按钮</button>
<script>
//获取元素
var puts = document.getElementsByTagName('input');
//循环添加获取焦点事件
for (let i = 0; i < puts.length; i++) {
//获取焦点事件
puts[i].onfocus = function () {
//排他思想:先把所有input清除样式
for (let j = 0; j < puts.length; j++) {
puts[j].style.backgroundColor = '';
}
//设置自己的样式
this.style.backgroundColor = 'yellow';
}
}
//我觉得还不如再给每个元素设置失去焦点事件,这样更节省性能,但是老师这么做应该是为了演绎排他思想
</script>
</body>
案例:点击更改样式
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
/* //默认样式 */
div {
width: 100px;
height: 100px;
background: pink;
}
/* 点击后样式 */
.new {
position: absolute;
left: 200px;
top: 200px;
width: 200px;
height: 200px;
background: skyblue;
}
</style>
<script>
//封装一个获取元素的函数
function hqys(x) {
//返回获取的元素
return document.getElementById(x);
}
</script>
</head>
<body>
<!-- 按钮 -->
<button id="button">给我变</button>
<!-- div -->
<div></div>
<script>
//获取元素
var button = hqys('button'),
div = document.getElementsByTagName('div')[0];
//两种方案,方案1--修改类名
button.onclick = function () {
div.className = 'new';
}
//方案2:直接修改style属性
// button.onclick = function () {
// div.style.position = 'absolute';
// div.style.left = '200px';
// div.style.top = '200px';
// div.style.width = '200px';
// div.style.height = '200px';
// div.style.backgroundColor = 'skyblue';
// }
//这种情况更推荐使用第一种方案,修改的类名比较多,第一种方案比较简单
</script>
</body>
案例:隔行变色和鼠标移上高亮显示
<body>
<table border="1" style="border-collapse: collapse;">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<script>
//获取元素
var trs = document.getElementsByTagName('tr');
// 循环遍历数组
for (let i = 0; i < trs.length; i++) {
// 设置偶数行背景色
if (i % 2 === 1) {
trs[i].style.backgroundColor = '#ccc';
}
// 记住事件发生前的背景色,要不然鼠标移开颜色不好设置
var bg = '';
//鼠标移上变色,并将变色之前的背景色保存一下
trs[i].onmouseover = function () {
bg = trs[i].style.backgroundColor;
trs[i].style.backgroundColor = 'yellow';
}
//鼠标移开恢复之前的颜色
trs[i].onmouseout = function () {
trs[i].style.backgroundColor = bg;
}
}
</script>
</body>
案例:tab页签切换效果
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style-type: none;
}
.box {
width: 400px;
height: 300px;
border: 1px solid #ccc;
margin: 100px auto;
overflow: hidden;
}
.hd {
height: 45px;
}
.hd span {
display: inline-block;
width: 90px;
background-color: pink;
line-height: 45px;
text-align: center;
cursor: pointer;
}
.hd span.current {
background-color: skyblue;
}
.bd div {
height: 255px;
background-color: skyblue;
display: none;
}
.bd div.current {
display: block;
}
</style>
<script>
// 定义一个获取元素的函数
function my$(id) {
return document.getElementById(id);
}
</script>
</head>
<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 spans = my$('hd').getElementsByTagName('span'),
divs = my$('bd').getElementsByTagName('div');
//循环遍历数组添加事件
for (var i = 0; i < spans.length; i++) {
//把这个span的下标存起来,使用自定义属性
spans[i].index = i;
//鼠标滑入事件
spans[i].onmouseover = function () {
//排他思想:清空所有class类名,再给需要的元素添加类名
//对应控制:因为spans和divs长度相同而且下标一一对应,那么可以使用同一个循环
for (var j = 0; j < spans.length; j++) {
//清除类名
spans[j].className = '';
//对应控制清除
divs[j].className = '';
}
//添加类名
this.className = 'current';
//对应控制添加:使用刚刚存起来的span下标
divs[this.index].className = 'current';
}
}
// 对应控制思想: 当我们有多组对象, 当一组发生变化, 另一组也会发生变化,这时我们可以找出两组数据的共同点,来进行对应关系的变成,比如案例中两组数据的下标是一一对应的
//下面代码可以实现和上面相同的效果,而且更简单,let创建变量可以很好的避免var的一些问题
// for (let i = 0; i < spans.length; i++) {
// spans[i].onmouseover = function () {
// for (let j = 0; j < spans.length; j++) {
// //清除类名
// spans[j].className = '';
// divs[j].className = '';
// }
// //添加类名
// this.className = 'current';
// divs[i].className = 'current'
// }
// }
</script>
</body>
</html>