1. 封装范围内随机整数
/*
封装范围内随机整数
1. 0 ~ 10 之间的随机整数
+ Math.random() 可以拿到 0 ~ 1
+ 乘以 10,
+ 取整
=> Math.floor()
=> Math.ceil()
=> Math.round()
+ 0 ~ 0.999 之间
=> * 10 以后, 0 ~ 9.999 之间
=> 向下取整, 0 ~ 9
=> 向上取整, 1 ~ 10
=> 四舍五入, 0 ~ 10
-> 0 ~ 0.499 0
-> 0.5 ~ 1.499 1
-> 8.5 ~ 9.499 9
-> 9.5 ~ 9.999 10
+ 方案2:
=> Math.random()
=> 乘以 (10 + 1)
=> 向下取整
=> 0 ~ 0.999 * 10 得到 0 ~ 10.999
=> 向下取整
-> 0 ~ 0.999 0
-> 1 ~ 1.999 1
-> 10 ~ 10.999 10
*/
// 1. 0 ~ 10 方案1
// var res = Math.round(Math.random() * 10)
// 成成若干个试一下
// var obj = {}
// for (var i = 0; i < 100000; i++) {
// var res = Math.round(Math.random() * 10)
// if (obj[res]) {
// obj[res]++
// } else {
// obj[res] = 1
// }
// }
// console.log(obj)
// 方案2
// var obj = {}
// for (var i = 0; i < 100000; i++) {
// var res = Math.floor(Math.random() * (10 + 1))
// if (obj[res]) {
// obj[res]++
// } else {
// obj[res] = 1
// }
// }
// console.log(obj)
/*
2. 0 ~ 20 的随机整数
=> Math.random() * (20 + 1)
=> 向下取整
*/
// var obj = {}
// for (var i = 0; i < 100000; i++) {
// var res = Math.floor(Math.random() * (20 + 1))
// if (obj[res]) {
// obj[res]++
// } else {
// obj[res] = 1
// }
// }
// console.log(obj)
/*
3.
+ 10 ~ 20 之间的随机整数
=> 取 0 ~ 10 之间的随机整数 + 10
+ 20 ~ 30 之间的随机整数
=> 0 ~ 10 之间的随机整数 + 20
+ 30 ~ 50 之间的随机整数
=> 0 ~ 20 之间的随机整数 + 30
+ 取 n ~ m 之间的随机整数
=> 取 0 ~ (m - n) 之间的随机整数 + n
+ 0 ~ 10 之间的随机整数
=> Math.random() * (10 + 1)
+ 0 ~ 20 之间的随机整数
=> Math.random() * (20 + 1)
+ 0 ~ (m - n) 之间的随机整数
=> Math.random() * (m - n + 1)
*/
// 去一个 10 ~ 20 之间的随机整数
// var n = 30
// var m = 50
// var obj = {}
// for (var i = 0; i < 100000; i++) {
// var res = Math.floor(Math.random() * (m - n + 1) + n)
// if (obj[res]) {
// obj[res]++
// } else {
// obj[res] = 1
// }
// }
// console.log(obj)
/*
把这段代码封装起来
1. 准备一个函数, 接收两个参数
2. 计算一个随机整数
3. 把随机整数返回
=> 只返回一个数字
*/
// 1. 准备函数
function rangeRandom(a, b) {
// 2. 计算随机整数
// 需要考虑谁大谁小
var max = Math.max(a, b)
var min = Math.min(a, b)
var res = Math.floor(Math.random() * (max - min + 1) + min)
// 3. 返回结果
return res
}
var n = 30
var m = 50
var obj = {}
for (var i = 0; i < 100000; i++) {
var res = rangeRandom(10, 20)
if (obj[res]) {
obj[res]++
} else {
obj[res] = 1
}
}
console.log(obj)
2. 生成一个随机颜色
/*
生成一个随机颜色
+ 几种表示方式
1. rgb()
2. 十六进制
+ 需要封装一个函数
=> 返回一个字符串, 是一个颜色的表示方法
=> 返回: 'rgb(255, 255, 255)'
=> 返回: '#FFFFFF'
=> 我们可以由一个参数决定, 你是返回一个 十六进制 还是 rgb
+ 需要一个函数, 接收一个参数
=> 表示是否是十六进制
=> true, 表示 十六进制
=> 不传递或者 false, 就表示 rgb
*/
function randomColor(type) {
if (!type) {
// 返回一个 rgb 颜色
var res = `rgb(${ rangeRandom(0, 255) }, ${ rangeRandom(0, 255) }, ${ rangeRandom(0, 255) })`
return res
}
// 代码能来带这里, 表示 type 是一个 true
// 生成一个 十六进制 的颜色, 返回
// 将来我要返回一个 #ABCDEF
// 前面 # 不变, 后面每两个数字是 0 ~ 255 的随机数字转成 16 进制
var str = '#'
// 循环一段代码执行三次
for (var i = 0; i < 3; i++) {
var n = rangeRandom(0, 255).toString(16)
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
// 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
// toString 返回值是一个 字符串, 可以直接判断 length
if (n.length === 1) {
n = '0' + n
}
console.log(n)
str += n
}
// 循环结束, str 就是拼接好的颜色
return str
}
console.log(randomColor(true))
3. 定时器
/*
定时器
单线程
+ 代码从上到下的执行
+ 一行一行的执行, 同时只能做一个事情
+ 例子: 一个厕所, 只有一个坑
同步异步
+ JS 是单线程同步代码机制
=> 当你写一个死循环的时候, 后面的代码就全都不执行了
+ WEBAPI 给我们提供了一个队列的机制
=> 用来模拟多线程
=> 准备了一个队列
=> 我们叫做单线程异步
+ 异步:
=> 不会立即执行的代码
=> 当代码从上到下的执行, 遇到异步代码的时候
=> 会把他放在队列里面, 先不执行
=> 等到所有同步代码执行完毕, 再从队列里面拿到代码来执行
JS 的定时器
+ JS 提供了两个异步定时器机制
1. setTimeout()
=> 语法: setTimeout(函数, 时间ms)
=> 时间到达的时候, 执行一遍函数就结束了
=> 延时定时器 / 炸弹定时器
2. setInterval()
=> 语法: setInterval(函数, 时间ms)
=> 每间隔固定时间, 执行一遍函数
=> 间隔定时器
*/
// 1. setTimeout()
// setTimeout(function () {
// console.log('timeout')
// }, 1000)
// 2. setInterval()
// setInterval(function () {
// console.log('interval')
// }, 500)
// 异步机制
// console.log('start')
// setTimeout(function () {
// console.log('timeout')
// }, 0)
// console.log('end')
// while (true) {} // 同步代码, 他没有结束
4. 定时器的返回值
<button id="btn">关闭定时器</button>
<script>
/*
定时器的返回值
+ 有返回值的
=> 不分定时器种类
=> 只表示你时页面中的第几个定时器
=> 就是一个 number 数据类型
+ 返回值的作用
=> 用来关闭定时器使用的
+ 关闭定时器
1. clearInterval()
=> 语法: clearInterval(要关闭的定时器返回值)
2. clearTimeout()
=> 语法: clearTimeout(要关闭的定时器返回值)
+ 关闭定时器时不分种类的, 随便关
+ 只要你的 定时器返回值时对的就可以
*/
var timer1 = setTimeout(function () { console.log('timeout') }, 1000)
var timer2 = setInterval(function () { console.log('interval') }, 1000)
console.log('timer1 ', timer1) // 1
console.log('timer2 ', timer2) // 2
// 点击 btn 的时候关闭定时器
btn.onclick = function () {
clearTimeout(timer2)
clearInterval(timer1)
}
</script>
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>
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
position: fixed;
bottom: 0;
right: 0;
border: 1px solid #333;
display: none;
}
</style>
</head>
<body>
<div id="box">
<button id="btn">X</button>
</div>
<script src="./utils.js"></script>
<script>
/*
广告弹出层
学一个知识点: 给元素设置 css 样式
+ 元素.style.样式名 = 值
分析:
1. 打开页面的时候不出来
=> box 盒子默认时隐藏的
2. 过一会显示出来
=> setTimeout()
=> 可以设置一个随机时间
3. 关闭按钮被点击的时候
=> 让 box 消失
=> 消失以后, 过一会还会出来
*/
// 2. 过一会显示出来
setTimeout(function () {
// 给 box 这个元素设置 display 为 block
box.style.display = 'block'
}, 1000 * rangeRandom(1, 3))
// 3. 点击关闭按钮, 让盒子消失
btn.onclick = function () {
// 让 box 消失
box.style.display = 'none'
setTimeout(function () {
// 给 box 这个元素设置 display 为 block
box.style.display = 'block'
}, 1000 * rangeRandom(1, 3))
}
</script>
</body>
</html>
6. 浏览器窗口尺寸
/*
浏览器窗口尺寸
+ 指的是 浏览器 可视窗口的尺寸
+ 浏览器有可能会出现滚动条
=> 再一般浏览器滚动条时算浏览器的一部分的
=> 再 MAC 上, 是不算的
+ 两个属性
1. innerWidth
2. innerHeight
+ 共同点: 包含滚动条的尺寸
*/
console.log(window.innerWidth)
console.log(window.innerHeight)
// 可以省略 window 不写
console.log(innerWidth)
console.log(innerHeight)
7. 浏览器的弹出层
/*
浏览器的弹出层
+ 再 BOM 里面, 给我们提供了三个弹出层
+ 可以再浏览器弹出一些信息
1. alert() 警告框
-> 弹出一段提示文本
-> 只有一个确定按钮
2. confirm() 选择框
-> 弹出一段提示文本
-> 有确定和取消两个按钮
3. prompt() 输入框
-> 弹出一个提示文本
-> 有一个 input 输入框
-> 有确定和取消按钮
语法:
1. alert()
语法: window.alert('提示文本')
返回值: undefined
2. confirm()
语法: window.confirm('提示文本')
返回值: 布尔值
-> 当用户点击确定的时候, 是 true
-> 当用户点击取消的hi收, 是 false
3. prompt()
语法: window.prompt('提示文本')
返回值:
-> 如果用户点击确定, 那么就是文本框里面的内容
-> 如果用户点击取消, 那么就是 null
共同点:
+ 会阻断程序的继续执行
=> 因为 JS 单线程
=> 弹出层弹出以后, 如果用户没有点击按钮表示当前弹出层没有结束
+ 直到用户操作以后, 才会继续向下执行代码
*/
// 1. alert()
// var res = window.alert('我是一段提示文本')
// console.log(res)
//confirm()
//var res = window.confirm('请选择')
// console.log(res)
// 3. prompt()
var res = window.prompt('请输入一段文本')
console.log(res)
console.log('后续代码')
8. 浏览器的地址栏
/*
浏览器的地址栏(重点)
+ 一个地址包含哪些内容(了解)
=> http://www.guoxiang.com?a=100&b=200#abc
=> http 传输协议
=> www.guoxiang.com 域名
=> ?a=100&b=200 查询字符串(queryString)
=> #abc 哈希(hash)
+ 地址里面包含的内容的作用(了解)
=> 传输协议: 前后端交互的方式
=> 域名: 找到一台服务器电脑
=> 查询字符串:
-> 不影响你打开页面
-> 打开这个页面的时候携带的信息
=> 哈希: 锚点定位
+ 再 window 下有一个成员叫做 location
=> location 是一个对象, 里面存储着和网页地址所有内容相关的信息
=> hash: 当前页面的 hash 值
=> href: 是一个读写的属性(当前地址栏地址)
-> 读: 获取当前打开的页面的地址(中文是 url 编码格式)
-> 写: 设置当前打开的页面的地址(跳转页面)
=> search: 当前地址中的 查询字符串(queryString)
-> 读: 查询到的是一个字符串
-> 这个是其他页面跳转到当前页面的时候带来的信息
-> 我们为了使用, 需要把他解析出来
+ location 里面 还有一个方法
=> reload()
=> 重新加载当前页面
=> 就相当于按下了浏览器左上角的刷新按钮
=> 注意: **不能写在打开页面就能执行的地方**
*/
// 1. href
// 读取
// console.log(window.location.href)
// 设置
// btn.onclick = function () {
// window.location.href = 'https://www.baidu.com'
// }
// 2. search
// 读取: 读取到当前地址的 查询字符串
// console.log(window.location)
// 3. reload()
// window.location.reload()
r.onclick = function () {
window.location.reload()
}
/*
解析查询字符串
+ 两种情况
1. ''
2. '?key=value&key=value'
步骤:
1. 准备一个函数接收一个参数
=> 参数: 要解析的查询字符串
2. 开始解析
2-1. 判断如果是空字符串, 直接返回 空对象
-> 如果不是空字符串, 要把字符串解析, 放在对象里面返回
-> 再最开始定义一个对象
-> 判断如果 str 有, 就向对象里面添加内容
-> 返回创建好的对象
2-2. 截取一部分字符串
-> ? 表示 queryString 的开始, 只要 ? 后面的不分
-> slice(1)
-> 使用 & 切割开
2-3. 循环这个切割好的数组
-> 拿到里面的每一项
-> 把每一项再次切割, 使用 = 切割
-> 切割好以后 [0] 就是对象的 key
-> [1] 就是对象的 value
*/
// var str = '?a=100&b=200'
// // var str = ''
// function parseQueryString(str) {
// var obj = {}
// if (str) {
// var tmp = str.slice(1).split('&')
// tmp.forEach(function (item) {
// var t = item.split('=')
// obj[t[0]] = t[1]
// })
// }
// return obj
// }
// var res = parseQueryString(str)
// console.log(res)
9. 浏览器的历史记录
/*
浏览器的历史记录
+ 操作浏览器前进后退
+ window 下有一个叫做 history 的成员
=> 是一个对象
=> 里面包含了一些操作历史记录的属性和方法
1. back()
=> 语法: window.history.back()
=> 作用: 回退到上一条历史记录, 相当于 ←
=> 前提: 你需要有历史记录, 不然没得回退
2. forward()
=> 语法: window.history.forward()
=> 作用: 前进到下一条历史记录, 相当于 →
=> 前提: 你需要会退过以后, 才可以操作
3. go()
=> 语法: window.history.go(整数)
-> 正整数: 表示前进
-> 0: 表示刷新当前页面
-> 负整数: 表示后退
*/
console.log(window.history)
10.浏览器的版本信息
/*
浏览器的版本信息(了解)
+ 用来区分浏览器
+ 再 window 下有一个成员叫做 navigator
=> navigator 是一个对象, 里面存储着浏览器的版本信息
1. userAgent
=> 表示浏览器的版本及型号信息
2. appName
=> 所有浏览器都是统一的名字 netscape
=> IE 低版本浏览器
=> IE 高版本也是 netscape
3. platform
=> 表示浏览器所在的操作系统
*/
// 1. userAgent
// console.log(window.navigator.userAgent)
// 2. appName
// console.log(window.navigator.appName)
// 3. platform
// console.log(window.navigator.platform)
11.浏览器的常见事件
<!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>
<script>
// 放在这里的时候, 是不可以操作 DOM 元素
// btn.onclick = function () {
// console.log('点击')
// }
// 等到页面所有资源加载完毕
// DOM 也是资源的一部分
// window.onload = function () {
// btn.onclick = function () {
// console.log('点击')
// }
// }
</script>
<style>
body {
width: 2000px;
height: 2000px;
}
</style>
</head>
<body>
<!--
<img src="https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg" alt="">
<img src="https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3892521478,1695688217&fm=26&gp=0.jpg" alt="">
<img src="https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1091405991,859863778&fm=26&gp=0.jpg" alt=""> -->
<button id="btn">按钮</button>
<script>
/*
浏览器的常见事件
+ 由浏览器行为触发的事件
1. window.onload = function () {}
=> 页面所有资源加载完毕后执行
=> 所有资源: 图片, 视频, 音频, ...
=> 作用: JS 前置
-> 当你需要把 JS 代码写在 head 标签里面的时候
-> 最好加上一个 window.onload
2. window.onscroll = function () {}
=> 浏览器滚动条滚动的时候触发
=> 不管横向还是纵向, 只要滚动就触发
=> 作用:
1. 楼层导航
2. 顶部通栏和回到顶部按钮的显示
3. 渐近显示页面
4. 瀑布流
3. window.onresize = function () {}
=> 浏览器可视窗口改变的时候触发
=> 只要改变就会触发
=> 一般结合 innerWidth 和 innerHeight 来判断屏幕尺寸
-> 移动端: 横屏
-> 响应式布局: 判断窗口大小
*/
// 1. onload
// window.onload = function () {
// console.log('资源加载完毕')
// }
// 2. onscroll
// window.onscroll = function () {
// console.log('滚动条再滚动')
// }
// 3. onresize
window.onresize = function () {
console.log('浏览器可视窗口改变大小了')
}
</script>
</body>
</html>
12.浏览器卷去的高度和宽度
/*
浏览器卷去的高度和宽度
+ 当页面比窗口宽或者高的时候
+ 会有一部分是随着滚动被隐藏的
+ 我们管 上面隐藏的叫做 卷去的高度
+ 我们管 左边隐藏的叫做 卷去的宽度
获取卷去的高度:
文档 html
1. document.documentElement.scrollTop
=> 使用必须要由 DOCTYPE 标签
2. document.body.scrollTop
=> 使用必须要没有 DOCTYPE 标签
3. 兼容写法
=> var scrollTop = document.documentElement.scrollTop || documentElement.body.scrollTop
=> || 当作短路表达式使用的
-> 当前面为 true 的时候, 那么就直接返回前面的值
-> 当前面为 false 的时候, 那么就返回后面的值, 不管后面是不是 false
获取卷去的宽度:
1. document.documentElement.scrollLeft
=> 使用必须要有 DOCTYPE 标签
2. document.body.scrollLeft
=> 使用必须没有 DOCTYPE 标签
3. 兼容的写法
=> var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
*/
// 1. scrollTop
window.onscroll = function () {
// console.log('html', document.documentElement.scrollTop)
// console.log('body', document.body.scrollTop)
// var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// console.log(scrollTop)
}
// 2. scrollLeft
window.onscroll = function () {
// console.log('有 ', document.documentElement.scrollLeft)
// console.log('没有 ', document.body.scrollLeft)
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
console.log(scrollLeft)
}
13.浏览器卷去的高度和宽度
/*
短路表达式
1. ||
2. &&
1. ||
+ 作用: 可以用 || 运算符分隔两个表达式
+ 如果前面的表达式结果为 true
=> 那么后面的就不执行了
=> 只有前面为 false 的时候, 才会执行后面的表达式
+ 当你使用 || 短路表达式赋值的时候
=> 前面表达式时 true, 那么就得到前面表达式的结果
=> 前面表达式是 false, 那么就得到后面表达式的结果
2. &&
+ 作用: 可以使用 && 运算符分隔两个表达式
+ 如果前面是 true, 那么后面的才会执行
=> 如果前面的是 false, 那么后面的就不执行了
+ 当你使用 && 短路表达式赋值的时候
=> 前面表达式是 true, 那么直接运算后面表达式的结果赋值
=> 前面表达式时 false, 那么直接把前面的结果返回
*/
// 1. ||
// false || alert('你好')
// 因为 1 + 1 是 true, 所以 n 得到的就是 1 + 1 的结果
// 后面的 10 + 10 不再执行了
// var n = 1 + 1 || 10 + 10
// 因为 1 - 1 是 false, 所以就会执行 10 + 10
// 不管 10 + 10 是不是 true, 得到的都是 10 + 10 的结果
// var n = 1 - 1 || ''
// console.log(n)
// 1 - 1 || 10 + 10 表达式的结果是 20
// 当 20 再 if 条件里面的时候就是 true
// if (1 - 1 || 10 + 10) {}
// 1 - 1 || 10 - 10 表达式的结果是 0
// 当 0 再 if 条件里面的时候就是 false
// if (1 - 1 || 10 - 10) {}
// 2. &&
// false && alert('你好')
// 因为 1 + 1 时 true, 所以一定会执行 后面的表达式
// 不管后面的表达式结果是什么, 都会把结果赋值给 n
// var n = 1 + 1 && 10 - 10
// 因为 1 - 1 是 false, 所以后面的表达式不再执行了
// 直接把 1 - 1 的结果赋值给 n
// var n = 1 - 1 && 10 + 10
// console.log(n)
14.浏览器滚动到
/*
浏览器滚动到
+ 通过 JS 代码指定 浏览器滚动到什么位置
1. scrollTo()
语法:
1. window.scrollTo(横向坐标, 纵向坐标)
=> 书写不需要单位, 给一个数字就可以了
=> 如果你传递数组, 必须两个参数, 一个参数报错
=> 特点: 瞬间定位
2. window.scrollTo({
top: 纵向坐标,
left: 横向坐标,
})
=> 对象里面写几个值无所谓
=> 特点: 可以依靠第三个配置项来决定是瞬间定位还是平滑滚动
-> behavior: 'smooth', 'instant'
-> 不能决定滚动时间
如果你想自己操作滚动时间
+ 需要自己来完成
*/
btn.onclick = function () {
// 让浏览器滚动到 300 500 的位置
// window.scrollTo(300)
// 语法2:
window.scrollTo({
top: 0,
left: 100,
// 决定定位方式
behavior: 'smooth'
})
}
15.自己完成浏览器回到顶部
<!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 {
height: 3000px;
}
button {
position: fixed;
bottom: 50px;
right: 50px;
}
</style>
</head>
<body>
<button id="btn">定位滚动条位置</button>
<script>
/*
自己完成浏览器回到顶部
1. document.documentElement.scrollLeft
document.documentElement.scrollTop
是读写的属性
可以获取可以设置
设置: 直接赋值就可以了
2. 定时器
=> 作用: 每间隔一段时间执行一次代码
=> 如果: 我每间隔 30ms, 让当前浏览器卷去的高度 - 20
3. 滚动以后, 就停不下来了
=> 因为你点击的时候, 开启了定时器
=> 这个定时器就一直存在
=> 解决问题
-> 直接再定时器里面判断
-> 当 卷去的高度 <= 0 的时候, 停止定时器
4. 假设你的滚动速度比较慢
=> 再没有滚动到指定位置的时候
=> 没有办法中断
=> 回到顶部, 是数字越来越小
-> 一旦下一次滚动比上一次滚动数字要大
-> 说明反方向再移动
-> 就要停下来
=> 浏览器滚动事件的时候做这个事情
-> 记录上一次的位置
*/
var timer = 0
btn.onclick = function () {
// 设置一个定时器, 来让滚动条向上滚动
timer = setInterval(function () {
document.documentElement.scrollTop -= 30
// 停止滚动到目标位置以后停止定时器
if (document.documentElement.scrollTop <= 0) {
clearInterval(timer)
}
}, 50)
}
// 再外面记录上一次的位置
var st = 0
// 滚动过程中, 你改变滚动方向, 停下来
window.onscroll = function () {
// 再你给 st 赋值之前, st 的值是上一次的值
// 进行比较
if (document.documentElement.scrollTop >= st) {
// 停止定时器
clearInterval(timer)
}
// 把当前位置赋值给 st
// 随着滚动记录每一次滚动的位置
st = document.documentElement.scrollTop
console.log(st)
}
</script>
</body>
</html>