1.BOM
概念: BOM(Browser Object Model) 是指浏览器对象模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。
通俗理解: 把浏览器当做对象,通过访问对象的属性,实现操作浏览器的一组方法
2. 页面加载事件
2.1 load事件
window.onload = function () {
// 当页面加载完所有内容(包括图像、脚本文件、CSS 文件等)执行
}
2.2 unload事件
window.onunload = function () {
// 当用户退出页面时执行(关闭页面)
}
小结:
window.onload事件 是页面所有资源加载完成时触发
window.onunload事件 是用户退出页面时触发
3.location对象
location 相当于浏览器地址栏的抽象, 通过window.location可以访问到,window可以忽略不写
我们学习location对象,目的是为了操作地址栏里面的url地址
3.1 URL
3.1.1 什么是url
概念:统一资源定位符 (Uniform Resource Locator, URL)
通俗理解: 互联网中的地址
3.1.2 URL的组成
-
scheme:通信协议
常用的http,ftp,maito等
-
host:主机 (找计算机)
服务器(计算机)域名系统 (DNS) 主机名或 IP 地址。
-
port:端口号 (找软件)
整数,可选,省略时使用方案的默认端口,如http的默认端口为80。
-
path:路径
由零或多个'/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。
-
query:查询
可选,用于给动态网页传递参数,可有多个参数,用'&'符号隔开,每个参数的名和值用'='符号隔开。
例如:name=zs
fragment: 信息片断
字符串,锚点.
3.2 location有哪些成员?
成员: 属性和方法又叫做成员
-
href 返回地址栏的整个url,设置值的时候,也可以起到跳转页面的作用
-
hash 返回地址栏url的fragment
-
host 返回地址栏url的主机名
-
search 返回地址栏url的键值对参数(query)
-
reload() 设置页面刷新
语法: location.reload([boolean])
参数是一个布尔值,不传参数则默认是false. 普通刷新,可能会从缓存拿数据
传true的话,是强制刷新.强制浏览器去服务器获取数据
- assign() 设置页面跳转,记录历史
语法: location.assign('url地址')
- replace() 设置页面跳转,不记录历史
语法:location.replace('url地址')
- href属性赋值,也可以是想页面跳转的新效果,跟assign类似
location.href = 'http://www.itheima.com';
小结:
-
location对象代表浏览器的地址栏.
-
学习location的目标主要是为了操作地址栏的url地址
-
网络中的地址我们称为url
4.history对象
-
back() 返回上一个页面
语法: history.back();
-
forward() 前进到下一个页面
语法: history.forward();
-
go(1/-1) 前进/ 返回
语法: history.go(number);
正数是前进,负数是后退.
history.go(1); //前进一步
history.go(2); //前进两步
history.go(-3); //后退三步
5.navigator对象
-
userAgent 返回识别客户端设备和浏览器的字符串
语法: navigator.userAgent
6. 定时器
6.1 设置定时器
6.1.1 setTimeout()
作用: 到达间隔时间之后,只调用一次回调函数
语法: window.setTimeout(回调函数, 间隔时间)
-
window可以省略
-
间隔时间以毫秒为单位
-
返回这个定时器的标识符,是数字类型
// 创建一个定时器,1秒后执行
// timerId指向这个定时器的标识符
var timerId = setTimeout(function () {
console.log('Hello World');
}, 1000);
6.1.2 setInterval()
作用: 每隔一个间隔时间,就调用一次回调函数
语法: window.setInterval(回调函数, 间隔时间)
window可以省略
间隔时间以毫秒为单位
返回这个定时器的唯一标示符,是数字类型
// 创建一个定时器,每隔1秒调用一次
//timerId 指向这个定时器的标识符
var timerId = setInterval(function () {
var date = new Date();
console.log(date.toLocaleTimeString());
}, 1000);
6.2 清除定时器
6.2.1 clearTimeout()
作用: 清除以setTimeout方法设置的定时器
语法: widnow.clearTimeout(定时器的标识符) window可以忽略
6.2.2 clearInterval()
作用: 清除以setInterval方法设置的定时器
语法: widnow.clearInterval(定时器的标识符) window可以忽略
小结:
-
设置定时器 setTimeout 和 setInterval
-
清除定时器 clearTimeout 和 clearInterval
简单动画案例
<!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;
}
#box{
width:100px;
height:100px;
background-color:red;
position:absolute;
}
</style>
</head>
<body>
<button id="btn">点击盒子移动到400</button>
<div id="box"></div>
</body>
</html>
<script>
//需求: 点击按钮,让box从左往右移动400px
// 1. 获取元素 btn, box
var btn = document.getElementById('btn');
var box = document.getElementById('box');
var pos = 400; //最终位置
var timeid; //一定要写在外面,用于存储定时器的id
// 2. 给btn注册点击事件
btn.onclick = function(){
//为了避免添加多个定时器的问题,所以每一次设置新的定时器之前,要先把原来的 清除掉
if(timeid){
clearInterval(timeid);
}
// 3. 在事件处理函数中让box动起来
//如果要让box自己动起来,需要把代码放到定时器里执行
timeid = setInterval(function(){
// 3.1 先获取当前的位置在哪
var current = box.offsetLeft;
// 3.2 在当前位置的基础上加几个像素
var target = current + 7;
box.style.left = target + 'px';
//3.3 判断一下是否到达了目标位置,如果到达了目标位置,就清除定时器
if(target >= pos){
clearInterval(timeid);
//如果超出了目标就直接拉回去(直接设置最终位置)
box.style.left = pos + 'px';
console.log(box.offsetLeft);
}
}, 15);
}
</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 type="text/css">
.time-item {
width: 430px;
height: 45px;
margin: 0 auto;
}
.time-item strong {
background: orange;
color: #fff;
line-height: 49px;
font-size: 36px;
font-family: Arial;
padding: 0 10px;
margin-right: 10px;
border-radius: 5px;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
}
.time-item > span {
float: left;
line-height: 49px;
color: orange;
font-size: 32px;
margin: 0 10px;
font-family: Arial, Helvetica, sans-serif;
}
.title {
width: 260px;
height: 50px;
margin: 200px auto 50px auto;
}
</style>
</head>
<body>
<h1 class="title">距离毕业,还有</h1>
<div class="time-item">
<span>
<span id="day">00</span>天</span>
<strong>
<span id="hour">00</span>时</strong>
<strong>
<span id="minute">00</span>分</strong>
<strong>
<span id="second">00</span>秒</strong>
</div>
<script>
// 需求:每隔一秒钟,就展示距离目标还差多长时间
// 获取元素:
var d = document.getElementById('day');
var h = document.getElementById('hour');
var m = document.getElementById('minute');
var s = document.getElementById('second');
// 5.让1-4步每隔一秒钟执行一次
fn();
setInterval(fn,1000);
function fn() {
// 1.获取到当前时间
var date = +new Date();
// 2.获取到目标事件
var target = +new Date('2020-04-10 00:00:00');
// 3.计算当前和目标的事件差
var time = target - date; //毫秒
time /= 1000; //把毫秒转换成秒
// 4.根据时间差,计算还差多少天,小时,分,秒
day = Math.floor(time/60/60/24);
hour = Math.floor(time/60/60%24);
minute = Math.floor(time/60 %60);
second = Math.floor(time % 60);
// 给元素的文本重新赋值
d.innerText = day;
h.innerText = hour;
m.innerText = minute;
s.innerText = second;
}
// 计算时间差的代码
// 先获得总共还有多少秒,然后计算天,小时,分,秒
// day = Math.floor(interval/60/60/24);
// hour = Math.floor(interval/60/60%24);
// minute = Math.floor(interval/60 %60);
// second = Math.floor(interval % 60);
</script>
</body>
</html>
6. 课后综合练习
钟表案例
7. 扩展内容@
7.1 name 和top 的特殊性:
name 和 top 是window 对象本身存在的属性
name 是字符串,给name赋值为其他类型,也会转换成字符串
top 是只读的属性,指向window对象,不可写
注意: 在全局申明变量,不要使用name 或者top
// name top
// console.log(window.name); //默认是一个空的字符串
// console.log(window.top); //指向window本身
// var a = 1;// 在全局申明一个变量,其实就相当于给window增加了一个属性
// window.a = 1;
// console.log(window.a);
var name = 1;
var name = false; //如果全局有name变量,不管你赋值的是什么数据类型,都会转成字符串
var top = 1; //如果全局有top变量,不管你赋值是什么,top永远指向window
console.log(name);
console.log(top);
// 结论: 在全局,不要使用name和top
8. 特效
8.1 offset系列
-
offsetParent 用于获取定位的父级元素
-
offsetLeft 距离定位父元素的左偏移量
-
offsetTop 距离定位父元素的上偏移量
-
offsetWidth 当前元素的宽度 content+padding+border
-
offsetHeight 当前元素的高度 content+padding+border
以下操作均是错误的:
son.offsetWidth = 300;
son.offsetWidth = '300px';
son.offsetLeft = 200;
son.offsetLeft = '200px';
son.offsetParent = document.body;
console.log(son.offsetParent);
//结论: offset系列不能赋值,只能获取
小问题:
offsetParent和parentNode的区别?
-
offsetParent 返回的是离自己最近的定位父元素
-
parentNode 返回的是直接父元素
8.2. client系列
-
clientWidth 元素可视区的宽度 content+padding
-
clientHeight 元素可视区的高度 content+padding
client系列也不可以赋值:
son.clientWidth = 300;
son.clientWidth = '300px';
// client系列同样也不可以赋值
8.3. scroll系列
-
scrollLeft 元素中内容左侧滚动出去的距离
-
scrollTop 元素中内容顶部滚动出去的距离
-
scrollWidth 元素中内容的宽度
-
scrollHeight 元素中内容的高度
scroll事件 ,监听滚动条滚动的事件
far.onscroll = function(){
// console.log(1);
console.log('left :' + far.scrollLeft);
console.log('top :' + far.scrollTop);
}
scrollLeft 和 scrollTop 可以赋值,并且不需要写单位
// far.scrollWidth = 600;
// far.scrollWidth = '600px';
// console.log(far.scrollWidth);
far.scrollLeft = 100;
far.scrollTop = 100;
console.log(far.scrollLeft);
console.log(far.scrollTop);
//结论: scrollLeft 和 scrollTop 可以赋值,并且不需要写单位
小结:
-
offset, client, scroll系列返回的都是数字类型(Number)
-
返回的值是所有样式渲染到页面上的最终结果
8.4. 获取浏览器可视区的大小(不可以被赋值)
-
window.innerWidth 浏览器可视区的宽度
-
window.innerHeight 浏览器可视区的高度
8.5.获取页面滚动出去的距离(也不可以被赋值)
-
window.pageYOffset 顶部滚动出去的距离
-
window.pageXOffset 左侧滚动出去的距离
9. 扩展内容@
9.1 client系列其他
-
clientLeft 返回元素左边框的宽度
-
clientTop 返回元素上边框的宽度
9.2 window.innerWidth 和 window.innerHeight的兼容问题
ie8及以下不支持
ie8及以下的浏览器中:
window.innerWidth ===> document.docuementELement.clientWidth
window.innerHeight ===> document.docuementELement.clientHeight
9.3 window.pageXOffset 和window.pageYOffset 的兼容问题
ie8及以下不支持
ie8及以下的浏览器中:
window.pageXOffset ===> document.docuementELement.scrollLeft
window.pageYOffset ===> document.docuementELement.scrollTop
拖拽案例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
.nav {
height: 30px;
background: #036663;
border-bottom: 1px solid #369;
line-height: 30px;
padding-left: 30px;
}
.nav a {
color: #fff;
text-align: center;
font-size: 14px;
text-decoration: none;
}
.d-box {
width: 400px;
height: 300px;
border: 5px solid #eee;
box-shadow: 2px 2px 2px 2px #666;
position: absolute;
top: 40%;
left: 40%;
background-color: white;
/* 不让文字被选中 */
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.hd {
width: 100%;
height: 25px;
background-color: #7c9299;
border-bottom: 1px solid #369;
line-height: 25px;
color: white;
cursor: move; /*将鼠标编程移动标示*/
}
#box_close {
float: right;
cursor: pointer;
}
</style>
</head>
<body>
<div class="nav">
<a href="javascript:void(0);" id="register">注册信息</a>
</div>
<div class="d-box" id="d_box">
<div class="hd" id="drop">注册信息 (可以拖拽)
<span id="box_close">【关闭】</span>
</div>
<div class="bd"></div>
</div>
</body>
</html>
<script>
//需求: 鼠标在drop上按下的时候,鼠标移动d-box跟着移动
// 1. 获取元素 drop d-box
var drop = document.getElementById('drop');
var d_box = document.getElementById('d_box');
// 2. 给drop注册鼠标按下事件 mousedown
drop.onmousedown = function(e){
// 4.2 获取鼠标按下的时候的坐标
var downX = e.clientX;
var downY = e.clientY;
//4.4 获取鼠标按下的一瞬间,d_box所处的位置
var posX = d_box.offsetLeft;
var posY = d_box.offsetTop;
// 3. 在按下的事件中注册鼠标移动的事件 mousemove
document.onmousemove = function(e){
console.log(1);
// 4. 在鼠标移动的事件处理函数中,给d-box设置位置
// 4.1 获取到鼠标浏览器可视区的坐标
var x = e.clientX;
var y = e.clientY;
// 4.3 计算鼠标移动了多少 鼠标移动的坐标 - 鼠标按下的坐标
var instanceX = x - downX;
var instanceY = y - downY;
// 4.5 计算d_box移动时,应该处于的位置 按下时的初识位置 + 鼠标移动的距离
var targetX = posX + instanceX;
var targetY = posY + instanceY;
d_box.style.left = targetX + 'px';
d_box.style.top = targetY + 'px';
}
}
//5.鼠标松开,d_box不在移动 mouseup
document.onmouseup = function(){
document.onmousemove = null;
}
</script>
弹出层拖拽案例:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.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 {
width: 512px;
height: 280px;
position: absolute;
border: #ebebeb solid 1px;
left: 50%;
right: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
margin-left: -256px;
margin-top: 140px;
display: none;
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
-moz-user-select: none;
/*火狐*/
-webkit-user-select: none;
/*webkit浏览器*/
-ms-user-select: none;
/*IE10*/
-khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
.login-input-content {
margin-top: 20px;
-moz-user-select: none;
/*火狐*/
-webkit-user-select: none;
/*webkit浏览器*/
-ms-user-select: none;
/*IE10*/
-khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
-moz-user-select: none;
/*火狐*/
-webkit-user-select: none;
/*webkit浏览器*/
-ms-user-select: none;
/*IE10*/
-khtml-user-select: none;
/*早期浏览器*/
user-select: none;
}
.login-bg {
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: #000000;
filter: alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
display: none;
}
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的href属性值中.协议名是javascript. 那么点击a标签的时候,就会执行:后面的代码-->
<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>
</body>
</html>
<script>
// 获取元素
var link = document.getElementById('link'); //点击的文字
var bg = document.getElementById('bg'); //遮盖层
var login = document.getElementById('login'); //登录框
var title = document.getElementById('title'); //登录框的标题
var closeBtn = document.getElementById('closeBtn');
// 需求:
// 1.点击文字,展示遮盖层和登录框
// 1.1获取元素
// 1.2 给link注册点击事件
link.onclick = function(){
//1.3 在事件处理函数中,让login和bg展示出来
login.style.display = 'block';
bg.style.display = 'block';
}
// 2. 鼠标在登录框的头部按下时,可以拖动
// 2.1 给title注册mousedown事件
title.onmousedown = function(e){
// 2.4 获取鼠标在title上按下的坐标
var downX = e.clientX;
var downY = e.clientY;
// 2.6 获取鼠标按下时,login的初始位置
var posX = login.offsetLeft;
var posY = login.offsetTop;
// 2.2 在mousedown中给document注册mousemove事件
document.onmousemove = function(e){
//2.3 获取鼠标移动的坐标
var x = e.clientX;
var y = e.clientY;
// 2.5 计算鼠标移动了多少 移动的坐标- 按下的坐标
var instanceX = x - downX;
var instanceY = y - downY;
//2.7 计算login最终处于的位置 鼠标移动的距离 + login初始的位置
var targetX = instanceX + posX;
var targetY = instanceY + posY;
// 3. 限制登录框的位置
// 3.1 获取最小距离和最大距离
var maxX = window.innerWidth - login.offsetWidth -21; //可视区的宽度 - login的宽度
var maxY = window.innerHeight - login.offsetHeight; //可视区的宽度 - login的宽度
// 3.2 判断target是否小于最小距离或者大于最大距离
if(targetX < 0){
targetX = 0;
}
if(targetY < 21){
targetY = 21;
}
if(targetX > maxX){
targetX = maxX;
}
if(targetY > maxY){
targetY = maxY;
}
//由于target算出来的就是login应该处于的位置,但是在最后渲染的一瞬间,css中的margin又作用到了login的身上,
// 导致位置发生了变化,为了抵消掉css中margin的值,所以应该在最后赋值的那一刻,把margin减掉
login.style.left = targetX + 256 + 'px';
login.style.top = targetY - 140 + 'px';
}
}
//2.8 松手,login不在移动
document.onmouseup = function(){
document.onmousemove = null;
}
</script>