1、BOM的组成结构
BOM:Brower Object Model,指的是浏览器对象模型。
作用:操作浏览器窗口及窗口上的控件,实现用户和页面的动态交互。
浏览器对象:浏览器提供的一系列内置对象的统称。
BOM浏览器对象模型:各内置对象之间按照某种层次组织起来的模型的统称。
window对象是BOM的顶层(核心)对象。
其他的对象都是以属性的方式添加到window对象下,也可称为window的子对象。
document(文档对象):也称为DOM对象,是HTML页面当前窗体的内容,同时也是JavaScript重要组成部分之一。
history(历史对象):主要用于记录浏览器的访问历史记录,也就是浏览网页的前进与后退功能。
location(地址栏对象):用于获取当前浏览器中URL地址栏内的相关数据。
navigator(浏览器对象):用于获取浏览器的相关数据,例如浏览器的名称、版本等,也称为浏览器的嗅探器。
screen(屏幕对象):可获取与屏幕相关的数据,例如屏幕的分辨率等。
注意:
BOM没有一个明确的规范,所以浏览器提供商会按照各自的想法随意去扩展BOM。而各浏览器间共有的对象就成为了事实上的标准。不过在利用BOM实现具体功能时要根据实际的开发情况考虑浏览器之间的兼容问题,否则会出现不可预料的情况。
2、window对象
window对象:是BOM中所有对象的核心,同时也是BOM中所有对象的父对象。
定义在全局作用域中的变量、函数以及JavaScript中的内置函数都可以被window对象调用。
<script>
var area = 'Beijing';
function getArea(){
return this.area;
}
console.log(area); // 访问变量,输出结果:Beijing
console.log(window.area); // 访问window对象的属性,输出结果:Beijing
console.log(getArea()); // 调用自定义函数,输出结果:Beijing
console.log(window.getArea()); // 调用window对象的方法,输出结果:Beijing
console.log(window.Number(area)); // 调用内置函数,将变量area转换为数值型,输出结果:NaN
</script>
定义在全局作用域中的getArea()函数,函数体内的this关键字指向window对象。
对于window对象的属性和方法在调用时可以省略window,直接访问其属性和方法即可。
注意:
在JavaScript中直接使用一个未声明的变量会报语法错误,但是使用“window.变量名”的方式则不会报错,而是获得一个undefined结果。除此之外,delete关键字仅能删除window对象自身的属性,对于定义在全局作用域下的变量不起作用。
(1)弹出对话框和窗口
示例:prompt()方法
作用:用于生成用户输入的对话框。
第1个参数:用于设置用户输入的提示信息。
第2个参数:用于设置输入框中的默认信息。
<script>
var str1 = prompt('请输入测试的选项');
var str2 = prompt('请输入测试的选项', '用户名和密码');
</script>
confirm()方法
作用:弹出一个确认对话框,该对话框中包含提示消息以及确认和取消按钮。
参数:用于设置确认的提示信息。
返回值:点击“确定”按钮,返回true。点击“取消”按钮,返回false。
<input type="button" value="删除" onclick="del()">
<script>
function del() {
if (confirm('确定要删除吗?')) {
// 你按下了“确定”按钮!
} else {
// 你按下了“取消”按钮!
}
}
</script>
open()方法
作用:用于打开一个新的浏览器窗口,或查找一个已命名的窗口。
语法:open(URL, name, specs, replace)。
第1个参数:打开指定页面的URL地址,若没有指定,则打开一个新的空白窗口。
第2个参数:指定target属性或窗口的名称。
第3个参数:用于设置浏览器窗口的特征(如大小、位置、滚动条等),多个特征之间使用逗号分隔。
第4个参数:设置为true,表示替换浏览历史中的当前条目,设置false(默认值),表示在浏览历史中创建新的条目。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>打开和关闭窗口</title>
</head>
<body>
<p><input type="button" value="打开窗口" onclick="openWin()"></p>
<p><input type="button" value="关闭窗口" onclick="closeWin()"></p>
<p><input type="button" value="检测窗口是否关闭" onclick="checkWin()"></p>
<p id="msg"></p>
<script>
var myWindow;
function openWin() {
myWindow = window.open('', 'newWin', 'width=400,height=200,left=200');
myWindow.document.write('<p>窗口名称为:' + myWindow.name + '</p>');
myWindow.document.write('<p>当前窗口的父窗口地址:' + window.parent.location + '</p>');
}
function closeWin() {
myWindow.close();
}
function checkWin() {
if (myWindow) {
var str = myWindow.closed ? '窗口已关闭!' : '窗口未关闭!';
} else {
var str = '窗口没有被打开!';
}
document.getElementById('msg').innerHTML = str;
}
</script>
</body>
</html>
与open()方法功能相反的是close()方法,用于关闭浏览器窗口,调用该方法的对象就是需要关闭的窗口对象。
(2)窗口位置和大小
BOM中用来获取或更改window窗口位置,窗口高度与宽度,文档区域高度与宽度的相关属性和方法有很多。
目前只有window.open()方法打开的的窗口和选项卡(Tab),FireFox和Chrome浏览器才支持口位置和大小的调整。
<script>
//bom称为浏览器对象模型(bowser object model),可以获取浏览器上所有的内容及相关操作
//window对象
console.log(window);//对象和window的构造函数
//常用的弹窗方法及打印方法
window.console.log('hello')//window 可以省略
console.log('日志');//控制台 log日志 以日志的形式打印
//以错误的形式打印
console.error('错误');
console.warn('警告');
//弹窗
window.alert('hello')
var isTrue=confirm('你确定要删除吗?')//交互框 true确认 false取消 返回
console.log(isTrue);
var str=prompt('请输入你的手机号')//输入框 返回的是string类型
//打开 关闭
//第一个参数是url地址,第二个是参数为title标题 target是设置打开方式,第三个参数为设置参数的(窗口的高度 宽度等)
window.open('http://www.baidu.com','_blank','width=300,height=100,top=0,left=0')
// 移动窗口位置
window.moveBy(100,100) //X+100 Y+100 移动位置
window.moveTo(200,200) //从当前位置移动
//改变对应窗口大小
window.resizeBy(200,200)//改变大小
window.resizeTo(200,200) //从当前修改大小
//print打印方法
window.print()
window.focus()//聚焦
window.blur()//失去焦点
//滚动条栏位置改变
window.scrollBy(100,100)//在原本位置上面移动
window.scrollTo(0,550)//到达位置 回到顶部
</script>
案例:窗口位置和大小
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>窗口位置和大小</title>
</head>
<body>
<input type="button" value="打开窗口" onclick="openWin()">
<input type="button" value="调整窗口位置和大小" onclick="changeWin()">
<script>
var myWindow;
function openWin() {
myWindow = window.open('', 'newWin', 'width=250,height=300');
getPosSize(); // 获取窗口信息
}
function changeWin() {
myWindow.moveBy(250, 250); // 将newWin窗口下移250像素,右移250像素
myWindow.focus(); // 获取移动后newWin窗口的焦点
myWindow.resizeTo(500, 350); // 修改newWin窗口的宽度为500,高度为350
getPosSize(); // 获取窗口信息
}
function getPosSize() {
// 获取相对于屏幕窗口的坐标
var x = myWindow.screenLeft, y = myWindow.screenTop;
// 获取窗口和文档的高度和宽度
var inH = myWindow.innerHeight, inW = myWindow.innerWidth;
var outH = myWindow.outerHeight, outW = myWindow.outerWidth;
myWindow.document.write('<p>相对屏幕窗口的坐标:(' + x + ',' + y + ')</p>');
myWindow.document.write('<p>文档的高度和宽度:' + inH + ',' + inW + '</p>');
myWindow.document.write('<p>窗口的高度和宽度:' + outH + ',' + outW + '</p><hr>');
}
</script>
</body>
</html>
(3)框架操作
window对象提供的frames属性可通过集合的方式,获取HTML页面中所有的框架,length属性就可以获取当前窗口中frames的数量。
<body>
<iframe name="frame01"></iframe>
<iframe name="frame02"></iframe>
<iframe name="frame03"></iframe>
</body>
<script>
console.log(window.frames.length);
// window.frames是个伪数组,可以通过window.frames[index]或window.frames[name]来获取iframe
// window.frames[index],索引是从左往右,从上往下的,从0开始,通常我们使用window.frames[name]来获取frame
// 方式1:
window.frames['frame01'].document.write('frame01 text.');
// 方式2:
window.frames.frame02.document.write('frame02 text.');
// 方式3:
window.frames[2].document.write('frame03 text.');
</script>
除此之外,还可以利用parent获取当前window对象所在的父窗口。
<script>
window.parent; // 如果在框架中,获取父级窗口,否则返回自身引用
window.parent.frames; // 获取同级别的框架
</script>
(4)定时器(重点)
JavaScript中可通过window对象提供的方法实现在指定时间后执行特定操作,也可以让程序代码每隔一段时间执行一次,实现间歇操作。
setTimeout()和setInterval()方法区别:
相同点:都可以在一个固定时间段内执行JavaScript程序代码。
不同点:setTimeout()只执行一次代码,setInterval()会在指定的时间后,自动重复执行代码。
<script>
setTimeout(echoStr, 3000);
function echoStr() {
console.log('JavaScript');
}
setInterval(echoStr, 3000);
</script>
提示
setTimeout()方法在执行一次后即停止了操作;setInterval()方法一旦开始执行,在不加干涉的情况下,间歇调用将会一直执行到页面关闭为止。
若要在定时器启动后,取消该操作,可以将setTimeout()的返回值(定时器ID)传递给clearTimeout()方法;或将setInterval()的返回值传递给clearInterval()方法。
案例:计数器
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>计数器</title>
</head>
<body>
<input type="button" value="开始计数" onclick="startCount()">
<input id="num" type="text">
<input type="button" value="停止计数" onclick="stopCount()">
<script>
var timer = null, c = 0;
function timedCount() { // 在文本框中显示数据
document.getElementById('num').value = c;
++c; // 显示数据加1
}
function startCount() { // 开始间歇调用
timer = setInterval(timedCount, 1000);
}
function stopCount() { // 清除间歇调用
clearInterval(timer);
}
</script>
</body>
</html>
案例:限时秒杀
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>限时秒杀</title>
<style>
.box div{float:left;width:50px;height:50px;border:1px solid #ccc;
line-height:50px;
text-align: center;color:red;}
</style>
</head>
<body>
<div class="box">
<div id="d"></div> <!-- 剩余的天数 -->
<div id="h"></div> <!-- 剩余的小时 -->
<div id="m"></div> <!-- 剩余的分钟 -->
<div id="s"></div> <!-- 剩余的秒数 -->
</div>
<script>
// 设置秒杀结束时间
var endtime = new Date('2023-03-07 18:51:00'), endseconds = endtime.getTime();
// 设置据当前时间开始,秒杀的结束时间
// var endtime = new Date(), endseconds = endtime.getTime() + 60 * 1000;
// 声明变量保存剩余的时间
var d = h = m = s = 0;
// 设置定时器,实现限时秒杀效果
var id = setInterval(seckill, 1000);
function seckill() {
var nowtime = new Date(); // 获取当前时间
// 获取时间差,单位秒
var remaining = parseInt((endseconds - nowtime.getTime()) / 1000);
// 判断秒杀是否过期
if (remaining > 0) {
d = parseInt(remaining / 86400); // 计算剩余天数(除以60*60*24取整,获取剩余的天数)
h = parseInt((remaining / 3600) % 24); // 计算剩余小时(除以60*60转换为小时,与24取模,获取剩余的小时)
m = parseInt((remaining / 60) % 60); // 计算剩余分钟(除以60转为分钟,与60取模,获取剩余的分钟)
s = parseInt(remaining % 60); // 计算剩余秒(与60取模,获取剩余的秒数)
// 统一利用两位数表示剩余的天、小时、分钟、秒
d = d < 10 ? '0' + d : d;
h = h < 10 ? '0' + h : h;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
} else {
clearInterval(id); // 秒杀过期,取消定时器
d = h = m = s = '00';
}
// 将剩余的天、小时、分钟和秒显示到指定的网页中
document.getElementById('d').innerHTML = d + '天';
document.getElementById('h').innerHTML = h + '时';
document.getElementById('m').innerHTML = m + '分';
document.getElementById('s').innerHTML = s + '秒';
}
</script>
</body>
</html>
3、location对象
(1)更改URL
URL:Uniform Resource Locator,统一资源定位符。
在Internet上访问的每一个网页文件,都有一个访问标记符,用于唯一标识它的访问位置,以便浏览器可以访问到,这个访问标记符称为URL。
location对象提供的用于改变URL地址的方法,所有主流的浏览器都支持。
reload()方法的唯一参数,是一个布尔类型值,将其设置为true时,它会绕过缓存,从服务器上重新下载该文档,类似于浏览器中的刷新页面按钮。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>更改URL</title>
</head>
<body>
<input type="button" value="载入新文档" onclick="newPage()">
<input type="button" value="刷新页面" onclick="freshPage()">
<p id="time"></p>
<script>
// 获取并显示当前页面载入的时间
var ds = new Date(), d = ds.getDate();
var t = ds.toLocaleTimeString();
document.getElementById('time').innerHTML = t;
// 载入新文档
function newPage() {
window.location.assign('https://www.baidu.com/')
}
// 刷新文档
function freshPage() {
location.reload(true);
}
</script>
</body>
</html>
(2)获取URL参数
利用location对象提供的search属性返回URL地址中的参数。
<script>
// 假设用户在地址栏中访问:http://localhost/search.html?goods=books&price=40 (需要搭建本地Web服务器)
location.search; // 在控制台即可获取的参数为:"?goods=books&price=40"
</script>
获取URL的指定部分:location.属性名。
设置URL的指定部分:location.属性名 = 值。
<script>
// 使用方式一: 获取URL地址:"file:///C:/JavaScript/test.html?name=Tom&age=12"
location.href;
// 使用方式二:设置URL地址
location.href = "http://www.example.com";
</script>
案例:定时跳转
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>定时跳转</title>
<style>
body{background:gray;}
div{margin:20px auto;width:350px;height:150px;border:1px solid #000;background:white;padding:10px;}
h2{text-align:center;}
span{font-size:150%;color:red;margin:0 10px;}
</style>
</head>
<body>
<div>
<h2>提交成功</h2>
<a href="http://www.example.com">
<span id="seconds">3</span>秒后系统会自动跳转,也可单击此链接跳转
</a>
</div>
<script>
//secs 跳转的时间 url 地址
function timing(secs, url) {
var seconds = document.getElementById('seconds');
// 自减
seconds.innerHTML = --secs;
// secs大于0继续计数,否则跳转到指定页面
if (secs > 0) {
setTimeout('timing(' + secs + ', \'' + url + '\')', 1000);
} else {
location.href = url;
}
};
timing(3, 'http://www.example.com');
</script>
</body>
</html>
4、history对象
(1)历史记录跳转
history对象可对用户在浏览器中访问过的URL历史记录进行操作。
出于安全方面的考虑,history对象不能直接获取用户浏览过的URL,但可以控制浏览器实现“后退”和“前进”的功能。
go()方法可根据参数的不同设置,完成历史记录的任意跳转。当参数值是一个负整数时,表示“后退”指定的页数;当参数值是一个正整数时,表示“前进”指定的页数。
当go()方法的参数为1或-1时,与forward()和back()方法的作用相同。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>历史记录跳转</title>
</head>
<body>
<input type="button" value="前进" onclick="goForward()">
<input type="button" value="新网页" onclick="newPage()">
<script>
function newPage() { // 打开一个新的文档
window.location.assign('show.html');
}
function goForward() { // 前进
history.go(1);
}
</script>
</body>
</html>
(2)无刷新更改URL地址
HTML5为history对象引入了history.pushState()和history.replaceState()方法,用来在浏览历史中添加和修改记录,实现无刷新更改URL地址。
pushState(state, title[, url]) // 添加历史记录
replaceState(state, title[, url]) // 修改历史记录
参数state:表示一个与指定网址相关的状态对象,此处可以填null或空字符串。
参数title:表示新页面的标题,可以填null或空字符串。
参数url:表示新的网址,并且必须与当前页面处在同一个域中。
<script>
history.pushState(null, null, '?a=check');
window.setTimeout(a,3000)
window.setTimeout(b,5000)
function a() {
history.pushState(null, null, '?a=login');
}
function b(){
history.replaceState(null, null, '?p=1')
}
</script>
pushState()方法会改变浏览器的历史列表中记录的数量。
replaceState()方法仅用于修改历史记录,历史记录列表的数量不变,与location.replace()方法的功能类似。
5、navigator对象
navigator对象提供了有关浏览器的信息,主流浏览器中存在的属性和方法如下。
<meta charset="UTF-8">
<script>
console.log('浏览器内部名称:' + navigator.appCodeName);
console.log('浏览器名称:' + navigator.appName);
console.log('是否启用cookie:' + navigator.cookieEnabled);
console.log('运行浏览器的操作系统平台:' + navigator.platform);
console.log('是否启用Java:' + navigator.javaEnabled());
console.log('浏览器平台与版本信息:' + navigator.appVersion);
console.log('User-Agent的值:' + navigator.userAgent);
</script>
6、screen对象
screen对象用于返回当前渲染窗口中与屏幕相关的属性信息,如屏幕的宽度和高度等。以下展示主流浏览器中支持的screen属性。
<script>
console.log(screen.height); // 示例结果:900
console.log(screen.availHeight); // 示例结果:870
console.log(screen.colorDepth); // 示例结果:24
console.log(screen.pixelDepth); // 示例结果:24
</script>
<script>
var img = new Image();
img.src = 'https://img2.baidu.com/it/u=2880544752,3222726160&fm=253&fmt=auto&app=138&f=GIF?w=502&h=215';
img.onload=function(e){
console.log(this.width+' '+this.height)
}
</script>
案例:红绿灯
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>红绿灯倒计时</title>
<style>
.box{width:250px;height:52px;padding:15px 30px;border:2px solid #ccc;border-radius:16px;margin:0 auto;}
.box .count{width:60px;color:#666;font-size:280%;line-height:50px;padding-left:6px;margin-left:5px;border:1px solid #fff}
.box div{margin-left:5px;float:left;width:50px;height:50px;border-radius:50px;border:1px solid #666;}
.gray{background-color:#eee;}
.red{background-color:red;}
.yellow{background-color:yellow;}
.green{background-color:#26ff00;}
</style>
</head>
<body>
<div class="box">
<div id="red"></div>
<div id="yellow"></div>
<div id="green"></div>
<div class="count" id="count"></div>
</div>
<script>
// 获取红、黄、绿灯以及倒计时的元素对象
var lamp = {
red: {
obj: document.getElementById('red'),
timeout: 30,
style: ['red', 'gray', 'gray'],
next: 'green'
},
yellow: {
obj: document.getElementById('yellow'),
timeout: 5,
style: ['gray', 'yellow', 'gray'],
next: 'red'
},
green: {
obj: document.getElementById('green'),
timeout: 35,
style: ['gray', 'gray', 'green'],
next: 'yellow'
},
changeStyle(style) {//设置信号背景颜色
this.red.obj.className = style[0];
this.yellow.obj.className = style[1];
this.green.obj.className = style[2];
}
};
// 设计倒计时的元素对象,实现倒计时的时间设置
var count = {
obj: document.getElementById('count'),
// num表示信号灯的倒计时时间,并以两位数字的格式将num显示到对应的位置
change: function(num) {
this.obj.innerHTML = (num < 10) ? ('0' + num) : num;
}
};
var now = lamp.green;//获取绿灯亮的相关数据
var timeout = now.timeout;//获取绿灯亮的剩余时间
lamp.changeStyle(now.style);//设置绿灯亮时,红绿灯背景色样式
count.change(timeout);//设置绿灯亮灯的剩余时间
setInterval(function() {
if (--timeout <= 0) {//切换信号灯
now = lamp[now.next];//获取下一个亮灯的信号灯的相关数据
timeout = now.timeout;//获取信号的的剩余时间
lamp.changeStyle(now.style);//设置信号灯背景样式
}
count.change(timeout);//设置信号灯亮灯的剩余时间
}, 1000);
</script>
</body>
</html>