小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
排他算法
如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:
-
所有元素全部清除样式(干掉其他人)
-
给当前元素设置样式 (留下我自己)
-
注意顺序不能颠倒,首先干掉其他人,再设置自己
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="div">
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<button>按钮6</button>
<button>按钮7</button>
</div>
<script>
// 获取元素
let btns = document.getElementsByTagName("button");
// 批量注册事件
for (let i = 0; i < btns.length; i++) {
// 注册为鼠标点击事件
btns[i].onclick = function () {
/* 每一次点击设置全部按钮没有颜色,然后再给点击的按钮一个颜色 */
// 循环设置全部按钮为默认值,即没有颜色
for (let j = 0; j < btns.length; j++) {
btns[j].style.backgroundColor = ""
}
// 点击按钮中的任意一个设置背景颜色为pink
this.style.backgroundColor = "pink";
}
}
</script>
</body>
</html>
百度换肤
- 案例分析
- 这个案例练习给一组元素注册事件
- 给4个小图片利用循环注册点击事件
- 当我们点击了这个图片,让我们页面背景改为当前的图片
核心算法:把当前图片的src路径去过来,给body做背景图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
background: url(./images/1.jpg) no-repeat center top;
}
li {
list-style: none;
}
.baidu {
overflow: hidden;
margin: 100px auto;
background-color: #fff;
width: 410px;
padding-top: 3px;
}
.baidu li {
float: left;
margin: 0 1px;
cursor: pointer;
}
.baidu img {
width: 100px;
}
</style>
</head>
<body>
<ul class="baidu">
<li><img src="./images/1.jpg"></li>
<li><img src="./images/2.jpg"></li>
<li><img src="./images/3.jpg"></li>
<li><img src="./images/4.jpg"></li>
</ul>
<script>
// 获取class是baidi的第一个元素,里面的标签名字是img的标签
let imgs = document.getElementsByClassName('baidu')[0].getElementsByTagName("img");
/* 批量注册 */
for (let i = 0; i < imgs.length; i++) {
// 鼠标点击img
imgs[i].onclick = () => {
// 设置页面的body的style里面的backgroundImage的路径为点击的图片的路径
document.body.style.backgroundImage = "url(" + imgs[i].src + ") ";
}
}
</script>
</body>
</html>
表格隔行变色
- 案例分析
核心思路:鼠标进过tr,当前的行变背景颜色,鼠标离开去掉当前的背景颜色- 鼠标移入(onmouseover)、鼠标移出(onmouseout)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table {
width: 800px;
margin: 100px auto;
text-align: center;
border-collapse: collapse;
font-size: 14px;
}
thead tr {
height: 30px;
background-color: skyblue;
}
tbody tr {
height: 30px;
}
tbody td {
border-bottom: 1px solid #d7d7d7;
font-size: 12px;
color: blue;
}
.bg {
background-color: pink;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>代码</th>
<th>名称</th>
<th>最新公布净值</th>
<th>累计净值</th>
<th>前单位净值</th>
<th>净值增长率</th>
</tr>
</thead>
<tbody>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
</tbody>
</table>
<script>
let tr = document.querySelector("tbody").querySelectorAll("tr");
//批量注册事件
for (let i = 0; i < tr.length; i++) {
// 鼠标移入让 tr 的样式修改成.bg里面的样式
tr[i].onmouseover = function () {
this.className = 'bg';
}
// 鼠标移出 tr 的样式修改成没有
tr[i].onmouseout = function () {
this.className = ""
}
}
</script>
</body>
</html>
全选和反选
- 案例分析
- 全选和反选:让下面所有复选框的checked属性(选中状态)跟随全选按钮。
- 下面复选框需要全部选中,上面全选才能选中:给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的,上面全选就不选中。 设置一个变量来控制全选是否选中。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
.wrap {
width: 300px;
margin: 100px auto 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 300px;
}
th,
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
}
td {
font: 14px "微软雅黑";
}
tbody tr {
background-color: #f0f0f0;
}
tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
</style>
</head>
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll" />
</th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_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>
</div>
<script>
// 全选按钮
let j_cbAll = document.querySelector("#j_cbAll");
// 单个按钮
let j_tbs = document.querySelector("#j_tb").querySelectorAll("input");
j_cbAll.onclick = function () {
for (let i = 0; i < j_tbs.length; i++) {
j_tbs[i].checked = this.checked;
console.log(this.checked);
}
}
// 已知选中是true,未选中是flase
for (let i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = function () {
let flag = true;
// 每一次点击按钮都会检查一遍所有的按钮是否被勾选上,如果都勾选上了,就让flag等于true就行了;
for (let i = 0; i < j_tbs.length; i++) {
if (j_tbs[i].checked == false) {
flag = false;
break;
}
}
j_cbAll.checked = flag;
}
}
</script>
</body>
</html>
Tab切换
-
业务需求
每一次点击标签下面的内容跟着变化
-
案例分析
Tab栏切换有2个大的模块 上的模块选项卡,点击某-个,当前这一 个底色会是红色,其余不变(排他思想) 修改类 名的方式 下面的模块内容,会跟随上面的选项卡变化。所以下面模块变化写到点击事件里面。 规律:下面的模块显示内容和上面的选项卡一 对应,相匹配。 核心思路:给上面的tab_ list里面的所有小i添加自定义属性,属性值从0开始编号。 当我们点击tab_ list 里面的某个小i,让tab_ con里面对应序号的内容显示,其余隐藏(排他 思想)
方法一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
.tab {
width: 978px;
margin: 100px auto;
}
.tab_list {
height: 39px;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab_list li {
float: left;
height: 39px;
line-height: 39px;
padding: 0 20px;
text-align: center;
cursor: pointer;
}
.tab_list .current {
background-color: #c81623;
color: #fff;
}
.item_info {
padding: 20px 0 0 20px;
}
.item {
display: none;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价(50000)</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item" style="display: block;">
商品介绍模块内容
</div>
<div class="item">
规格与包装模块内容
</div>
<div class="item">
售后保障模块内容
</div>
<div class="item">
商品评价(50000)模块内容
</div>
<div class="item">
手机社区模块内容
</div>
</div>
</div>
<script>
// 获取切换栏
let tab_lists = document.querySelector(".tab_list").querySelectorAll("li");
// 获取切换内容
let tab_cons = document.getElementsByClassName("tab_con")[0].getElementsByTagName("div");
// 批量注册事件
for (let i = 0; i < tab_lists.length; i++) {
tab_lists[i].onclick = function () {
// 排他算法开始
for (let j = 0; j < tab_lists.length; j++) {
// 1 每一次点击都移除掉 li标签的 class属性
tab_lists[j].removeAttribute("class");
}
// 2 然后再添加css属性上去
tab_lists[i].className = "current";
// 排他算法结束
// 内容显示模块开始,核心排他算法
for (let p = 0; p < tab_cons.length; p++) {
// 1 每一次点击都清空div里面的style属性
tab_cons[p].removeAttribute("style");
// tab_cons[p].style.display = '';
}
// 2 然后再添加行内式上去
tab_cons[i].style.display = 'block';
// 内容显示模块结束
}
}
</script>
</body>
</html>
方法二
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
.tab {
width: 978px;
margin: 100px auto;
}
.tab_list {
height: 39px;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab_list li {
float: left;
height: 39px;
line-height: 39px;
padding: 0 20px;
text-align: center;
cursor: pointer;
}
.tab_list .current {
background-color: #c81623;
color: #fff;
}
.item_info {
padding: 20px 0 0 20px;
}
.item {
display: none;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价(50000)</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item" style="display: block;">
商品介绍模块内容
</div>
<div class="item">
规格与包装模块内容
</div>
<div class="item">
售后保障模块内容
</div>
<div class="item">
商品评价(50000)模块内容
</div>
<div class="item">
手机社区模块内容
</div>
</div>
</div>
<script>
// 获取切换栏
let tab_lists = document.querySelector(".tab_list").querySelectorAll("li");
// 获取切换内容
let tab_cons = document.getElementsByClassName("tab_con")[0].getElementsByTagName("div");
// 批量注册事件
for (let i = 0; i < tab_lists.length; i++) {
// 给5个li设置自定义属性
tab_lists[i].setAttribute("index", i);
tab_lists[i].onclick = function () {
// 排他算法开始
for (let j = 0; j < tab_lists.length; j++) {
// 1 每一次点击都移除掉 li标签的 class属性
tab_lists[j].removeAttribute("class");
}
// 2 然后再添加css属性上去
tab_lists[i].className = "current";
// 排他算法结束
// 内容显示模块开始,核心排他算法
let index = tab_lists[i].getAttribute("index");
console.log(index);
for (let i = 0; i < tab_cons.length; i++) {
// tab_cons[i].style.display = "";
tab_cons[i].removeAttribute("style");
}
tab_cons[index].style.display = "block";
// 内容显示模块结束
}
}
</script>
</body>
</html>
新浪下拉菜单
案例分析
核心代码
<script>
// 1. 获取元素
var nav = document.querySelector('.nav');
var lis = nav.children; // 得到4个小li
// 2.循环注册事件
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
this.children[1].style.display = 'block';
}
lis[i].onmouseout = function() {
this.children[1].style.display = 'none';
}
}
</script>
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
font-size: 14px;
}
.nav {
margin: 100px;
}
.nav>li {
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
color: #333;
}
.nav>li>a:hover {
background-color: #eee;
}
.nav ul {
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #FECC5B;
border-right: 1px solid #FECC5B;
}
.nav ul li {
border-bottom: 1px solid #FECC5B;
}
.nav ul li a:hover {
background-color: #FFF5DA;
}
</style>
</head>
<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
</ul>
<script>
/* 获取nav */
let navs = document.getElementsByClassName('nav')[0];
/* 获取nav里面所有的li */
let lis = navs.children;
for (let i = 0; i < lis.length; i++) {
lis[i].onmouseover = function () {
/* 获取li里面的所有子元素 a 和 ul 选择下标为1的ul进行显示 */
this.children[1].style.display = "block";
}
lis[i].onmouseout = function () {
this.children[1].style.display = "none";
}
}
</script>
</body>
</html>
简单版留言发布
案例分析
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
width: 200px;
height: 100px;
border: 1px solid pink;
outline: none;
resize: none;
}
ul {
margin-top: 50px;
}
li {
width: 300px;
padding: 5px;
background-color: rgb(245, 209, 243);
color: red;
font-size: 14px;
margin: 15px 0;
}
</style>
</head>
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul>
</ul>
<script>
/* 获取元素 */
let btn = document.querySelector("button");
let text = document.querySelector("textarea");
let ul = document.querySelector("ul");
/* 注册事件 */
btn.onclick = function () {
if (text.value == "") {
alert("你没有输入内容");
return false;
} else {
/* 创建元素 */
let li = document.createElement("li");
/* 添加textarer里面的内容到li里面 */
li.innerHTML = text.value;
/* 添加元素 */
// ul.appendChild(li);
ul.insertBefore(li, ul.children[0]);
}
}
</script>
</body>
</html>
删除留言
案例分析
<textarea name="" id=""></textarea>
<button>发布</button>
<ul>
</ul>
<script>
// 1. 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2. 注册事件
btn.onclick = function() {
if (text.value == '') {
alert('您没有输入内容');
return false;
} else {
// console.log(text.value);
// (1) 创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
// (2) 添加元素
// ul.appendChild(li);
ul.insertBefore(li, ul.children[0]);
// (3) 删除元素 删除的是当前链接的li 它的父亲
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// 删除的是 li 当前a所在的li this.parentNode;
ul.removeChild(this.parentNode);
}
}
}
}
</script>
动态生成表格创建学生数据
案例分析
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1.先去准备好学生的数据
var datas = [{
name: '魏璎珞',
subject: 'JavaScript',
score: 100
}, {
name: '弘历',
subject: 'JavaScript',
score: 98
}, {
name: '傅恒',
subject: 'JavaScript',
score: 99
}, {
name: '明玉',
subject: 'JavaScript',
score: 88
}, {
name: '大猪蹄子',
subject: 'JavaScript',
score: 0,
},
];
// 在tbody里面创建行
let tbody = document.querySelector("tbody");
/* 创建单元格 */
for (let i = 0; i < datas.length; i++) {
/* 创建tr行 */
let tr = document.createElement("tr");
/* 控制新添加的在前面 */
tbody.insertBefore(tr, tbody.children[0]);
/* 行里面创建单元格 */
/* 行里面创建单元格td 单元格的数量取决于每个对象的属性个数 所以使用for循环遍历对象 */
for (let k in datas[i]) {
// 创建单元格
let td = document.createElement("td");
/* 把对象里面的属性值给td */
td.innerHTML = datas[i][k];
// console.log(datas[i][k]); //至于为什么用append添加进去请打开我
/* 在tr里面从创建td 始终创建在最后面 */
tr.appendChild(td)
// tr.insertBefore(td, tr.children[0]);
}
/* 创建有 删除单元格 */
let td = document.createElement("td");
tr.append(td);
td.innerHTML = "<a href='javascript:;'>删除</a>"
}
/* 为什么删除操作要写在for循环外面,因为上面的for循环是创建单元格使用的,创建完成之后就是删除操作所以放外面 */
// 删除操作
let as = document.querySelectorAll("a");
for (let i = 0; i < as.length; i++) {
as[i].onclick = function () {
/* 删除的是tbody里面的行 因为a标签在td里面 td在tr里面 所以删除的是a的爷爷 */
tbody.removeChild(as[i].parentNode.parentNode);
}
}
</script>
</body>
</html>
案例:禁止选中文字和禁止右键菜单
<body>
我是一段不愿意分享的文字
<script>
// 1. contextmenu 我们可以禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
// 2. 禁止选中文字 selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
</script>
</body>
案例:跟随鼠标的天使
<img src="images/angel.gif" alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e) {
// 1. mousemove只要我们鼠标移动1px 就会触发这个事件
// 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标,
// 把这个x和y坐标做为图片的top和left 值就可以移动图片
var x = e.pageX;
var y = e.pageY;
console.log('x坐标是' + x, 'y坐标是' + y);
//3 . 千万不要忘记给left 和top 添加px 单位
pic.style.left = x - 50 + 'px';
pic.style.top = y - 40 + 'px';
});
</script>
案例:5秒后关闭广告
<body>
<img src="images/ad.jpg" alt="" class="ad">
<script>
// 获取要操作的元素
var ad = document.querySelector('.ad');
// 开启定时器
setTimeout(function() {
ad.style.display = 'none';
}, 5000);
</script>
</body>
停止定时器
<button>点击停止定时器</button>
<script>
var btn = document.querySelector('button');
// 开启定时器
var timer = setTimeout(function() {
console.log('爆炸了');
}, 5000);
// 给按钮注册单击事件
btn.addEventListener('click', function() {
// 停止定时器
clearTimeout(timer);
})
</script>
案例:倒计时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body {
background-color: #000;
}
div {
margin: 200px;
}
span {
display: inline-block;
width: 40px;
height: 40px;
background-color: #333;
font-size: 20px;
color: #fff;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div>
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span>
</div>
<script>
// 1. 获取元素
var hour = document.querySelector('.hour'); // 小时的黑色盒子
var minute = document.querySelector('.minute'); // 分钟的黑色盒子
var second = document.querySelector('.second'); // 秒数的黑色盒子
// 因为要延迟一秒才显示,所以先调用一次
countTime();
setInterval(() => {
countTime();
}, 1000);
function countTime() {
// 设定一个倒计时的时间
var endTime = +new Date("2020-02-15 17:00:00");
// var endTime = +new Date("2020-02-14 21:00:00");
// console.log(endTime);
// 获取当前时间
var nowTime = +new Date();
// console.log(nowTime);
// 求两个时间的差的总秒数
var times = parseInt((endTime - nowTime) / 1000);
// console.log(times);
// 求相差的小时
var h = parseInt(times / 60 / 60 % 24);
// console.log(h);
h = h < 10 ? "0" + h : h;
hour.innerHTML = h;
// 求相差的分钟
var f = parseInt(times / 60 % 60);
f = f < 10 ? "0" + f : f;
minute.innerHTML = f;
// console.log(f);
// 求相差的秒
var m = parseInt(times % 60);
m = m < 10 ? "0" + m : m;
second.innerHTML = m;
// console.log(m);
}
</script>
</body>
</html>
案例:5分钟自动跳转页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>点击</button>
<div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
// btn.addEventListener('click', function () {
// // console.log(location.href);
// location.href = 'http://www.baidu.com';
// })
btn.addEventListener("click", function () {
var timer = 5;
setInterval(function () {
if (timer === 0) {
location.href = "https://www.baidu.com";
} else {
div.innerHTML = "还剩下" + timer + "秒跳转至百度";
timer--;
}
}, 1000)
})
</script>
</body>
</html>
案例:获取URL参数
<div></div>
<script>
console.log(location.search); // ?uname=andy
// 1.先去掉? substr('起始的位置',截取几个字符);
var params = location.search.substr(1); // uname=andy
console.log(params);
// 2. 利用=把字符串分割为数组 split('=');
var arr = params.split('=');
console.log(arr); // ["uname", "ANDY"]
var div = document.querySelector('div');
// 3.把数据写入div中
div.innerHTML = arr[1] + '欢迎您';
</script>
案例:获取鼠标在盒子内的坐标
- 我们在盒子内点击,想要得到鼠标距离盒子左右的距离。
- 首先得到鼠标在页面中的坐标(e.pageX, e.pageY)
- 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop)
- 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标
- 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动
let box = document.getElementsByClassName("box")[0];
box.addEventListener("mousemove", function (e) {
console.log(e.pageX);
console.log(e.pageY);
// 页面文档的左边
let dx = e.pageX;
let dy = e.pageY;
console.log(box.offsetTop)
console.log(box.offsetLeft)
// 盒子距离文档的距离
let bx = box.offsetTop;
let by = box.offsetTop;
box.innerHTML = "鼠标距离盒子左边的距离是" + (dx - bx) + "</br>" + "鼠标距离盒子上边的距离是" + (dy - by);
})
案例:模态框拖拽
弹出框,我们也称为模态框。
1.点击弹出层,会弹出模态框, 并且显示灰色半透明的遮挡层。
2.点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层。
3.鼠标放到模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动。
4.鼠标松开,可以停止拖动模态框移动
案例分析:
- 点击弹出层, 模态框和遮挡层就会显示出来 display:block;
- 点击关闭按钮,模态框和遮挡层就会隐藏起来 display:none;
- 在页面中拖拽的原理:鼠标按下并且移动, 之后松开鼠标
- 触发事件是鼠标按下mousedown,鼠标移动mousemove 鼠标松开 mouseup
- 拖拽过程: 鼠标移动过程中,获得最新的值赋值给模态框的left和top值,这样模态框可以跟着鼠标走了
- 鼠标按下触发的事件源是最上面一行,就是 id 为 title
- 鼠标的坐标减去 鼠标在盒子内的坐标, 才是模态框真正的位置。
- 鼠标按下,我们要得到鼠标在盒子的坐标。
- 鼠标移动,就让模态框的坐标 设置为 :鼠标坐标 减去盒子坐标即可,注意移动事件写到按下事件里面。
- 鼠标松开,就停止拖拽,就是可以让鼠标移动事件解除
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.login-header {
width: 100%;
text-align: center;
height: 30px;
font-size: 24px;
line-height: 30px;
}
ul,
li,
ol,
dl,
dt,
dd,
div,
p,
span,
h1,
h2,
h3,
h4,
h5,
h6,
a {
padding: 0px;
margin: 0px;
}
.login {
display: none;
width: 512px;
height: 280px;
position: fixed;
border: #ebebeb solid 1px;
left: 50%;
top: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
transform: translate(-50%, -50%);
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
}
.login-input-content {
margin-top: 20px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
}
.login-bg {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, .3);
}
a {
text-decoration: none;
color: #000000;
}
.login-button a {
display: block;
}
.login-input input.list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-title span {
position: absolute;
font-size: 12px;
right: -20px;
top: -30px;
background: #ffffff;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
<div id="login" class="login">
<div id="title" class="login-title">登录会员
<span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
</div>
<div class="login-input">
<label>登录密码:</label>
<input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
</div>
</div>
<div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<!-- 遮盖层 -->
<div id="bg" class="login-bg"></div>
<script>
// 1. 获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// 2. 点击弹出层这个链接 link 让mask 和login 显示出来
link.addEventListener("click", () => {
mask.style.display = "block";
login.style.display = "block";
})
// 3. 点击 closeBtn 就隐藏 mask 和 login
closeBtn.addEventListener("click", function () {
mask.style.display = "none";
login.style.display = "none";
})
// 4. 开始拖拽
// (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
title.addEventListener("mousedown", function (e) {
console.log(e.pageX)
console.log(e.pageY)
// console.log(login.offsetLeft)
// console.log(login.offsetTop)
// 获得鼠标在盒子内的坐标
let x = e.pageX - login.offsetLeft;
let y = e.pageY - login.offsetTop;
// page减去鼠标在盒子内的坐标就得到了我们要移动的数值
// 鼠标移动的时候不断的把page-x的值给模态框
document.addEventListener("mousemove", move)
function move(e) {
login.style.left = e.pageX - x + "px";
login.style.top = e.pageY - y + "px";
}
// 鼠标松开的时候就给定数值了,及移除事件
document.addEventListener("mouseup", function () {
document.removeEventListener("mousemove", move);
})
})
</script>
</body>
</html>
案例:仿京东放大镜
- 整个案例可以分为三个功能模块
- 鼠标经过小图片盒子, 黄色的遮挡层 和 大图片盒子显示,离开隐藏2个盒子功能
- 黄色的遮挡层跟随鼠标功能。
- 移动黄色遮挡层,大图片跟随移动功能。
1.1.7. 案例分析:
- 黄色的遮挡层跟随鼠标功能。
- 把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准。
- 首先是获得鼠标在盒子的坐标。
- 之后把数值给遮挡层做为left 和top值。
- 此时用到鼠标移动事件,但是还是在小图片盒子内移动。
- 发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半。
- 遮挡层不能超出小图片盒子范围。
- 如果小于零,就把坐标设置为0
- 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
- 遮挡层的最大移动距离:小图片盒子宽度 减去 遮挡层盒子宽度
window.addEventListener('load', function() {
var preview_img = document.querySelector('.preview_img');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子
preview_img.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
preview_img.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
// 2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
preview_img.addEventListener('mousemove', function(e) {
// (1). 先计算出鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// console.log(x, y);
// (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了
// (3) 我们mask 移动的距离
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
// (4) 如果x 坐标小于了0 就让他停在0 的位置
// 遮挡层的最大移动距离
var maskMax = preview_img.offsetWidth - mask.offsetWidth;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
// 大图
var bigIMg = document.querySelector('.bigImg');
// 大图片最大移动距离
var bigMax = bigIMg.offsetWidth - big.offsetWidth;
// 大图片的移动距离 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigIMg.style.left = -bigX + 'px';
bigIMg.style.top = -bigY + 'px';
})
})