主要涉及BOM下五大对象,包括window 对象、location 对象、history 对象、navigator 对象、screen 对象。
javascript 的组成部分:
- DOM (document object model) 文档对象模型
- BOM (browers object model) 浏览器对象模型
- ECMAScript js 的核心
DOM是一套标准,有DOM1/2/3,现在常用的是DOM2/3。ECMAScript也有标准,但是BOM本身没有标签,所有各浏览器不一定都兼容。
1.window对象
- innerWidth/innerHeight
- open 方法
window.open(URL,target,specs,replace)
- URL 新窗口地址
- target 属性 新窗口打开方式
- _blank
- _self
- specs 新窗口规格
- width=pixels 窗口的宽度.最小.值为100
- height=pixels 窗口的高度。最小.值为100
- location=yes|no|1|0 是否显示地址字段.默认值是yes
- menubar=yes|no|1|0 是否显示菜单栏.默认值是yes
- resizable=yes|no|1|0 是否可调整窗口大小.默认值是yes
- scrollbars=yes|no|1|0 是否显示滚动条.默认值是yes
- status=yes|no|1|0 是否要添加一个状态栏.默认值是yes
- titlebar=yes|no|1|0 是否显示标题栏.被忽略,除非调用HTML应用程序或一个值得信赖的对话框.默认值是yes
- toolbar=yes|no|1|0 是否显示浏览器工具栏.默认值是yes
- close 方法关闭窗口
- scroll 事件
- resize 事件
- 操作滚动条位置
- window.scrollX、window.scrollY、window.scrollTo()
- document.documentElment.scrollTop、document.documentElment.scrollLeft
- window 下的各类弹窗
- alert()
- confirm('message')
- prompt([msg],[defaultText])
1.1 window下的innerWidth/innerHeight
- window.innerWidth 可视区宽度
- window.innerHeight 可视区高度
可视区宽高(浏览器的可见宽高)方法会根据浏览器缩放宽高不一致。调用window下方法时,window皆可省略
console.log(window.innerWidth,window.innerHeight);
console.log(innerWidth,innerHeight);
1.2 window下的open()/close()方法
open()方法为打开一个新窗口。由于有些恶意弹窗,可以现行的一些浏览器版本会阻止新窗口生成。
window.open(URL,target,specs,replace):
- 三个参数:
- URL 新窗口地址;
- target 属性 新窗口打开方式:_blank打开一个新的窗口;_self在当前窗口打开;其他的打开方式现在基本不用了
- specs 新窗口规格(兼容性不是很好。各参数之间使用逗号隔开):
- - width=pixels 窗口的宽度.最小.值为100
- - height=pixels 窗口的高度。最小.值为100
- - location=yes|no|1|0 是否显示地址字段.默认值是yes
- - menubar=yes|no|1|0 是否显示菜单栏.默认值是yes
- - resizable=yes|no|1|0 是否可调整窗口大小.默认值是yes
- - scrollbars=yes|no|1|0 是否显示滚动条.默认值是yes
- - status=yes|no|1|0 是否要添加一个状态栏.默认值是yes
- - titlebar=yes|no|1|0 是否显示标题栏.被忽略,除非调用HTML应用程序或一个值得信赖的对话框.默认值是yes
- - toolbar=yes|no|1|0 是否显示浏览器工具栏.默认值是yes
window.close() 方法关闭窗口。注意:这个window必须是记录的打开的window,如果直接使用window.close()会将原来窗口和新打开的窗口一起关闭。
let btn = document.querySelector("button");
btn.onclick = () =>{
let win = window.open("http://www.baidu.com","_blank","width=400px,height=400px,location=no");
//window.close关闭窗口
setTimeout(()=>{
win.close();
},3000);
};
1.3 window 下的各类弹窗
实际项目中这些方法用的比较少,因为样式太丑。
- alert():点击弹出提示消息
- confirm('message'):点击确定返回true,点击取消返回false
- prompt([msg],[defaultText]):可以输入内容。第一个参数:提示信息;第二个参数:文本框默认值;返回值:文本框输入的内容
// alert("弹出消息");
// confirm("是否删除信息");
let val = prompt("你今天锻炼了吗?","打羽毛球");
console.log(val);//打羽毛球,兵乓球
1.4 onscroll 事件/onresize事件/获取及设置滚动条位置
- 获取自身元素宽高:offsetWidth、offsetHeight
- 获取可视区宽高:innerWidth、innerHeight
- onscroll事件:滚动条滚动时触发
- window.onresize事件:窗口缩放时触发,监听窗口大小的改变
- 获取滚动条位置:window.scrollY获取纵向滚动条位置;window.scrollX获取横向滚动条位置;window.scroll(x,y)同时设置横向和纵向滚动条的位置(Chrome/Firefox/移动端)
- IE下获取滚动条位置:document.body.scrollLeft 获取横向滚动条位置和document.body.scrollTop获取纵向滚动条位置
- 若只使用document.body.scrollLeft 和document.body.scrollTop则在chrome等浏览器下会获取不到,所以需要设置兼容document.documentElement.scrollLeft 和document.documentElement.scrollTop
- 所以一般获取滚动条位置时:let scrollTop = document.documentElement.scrollTop || ocument.body.scrollTop; let scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
- 设置滚动条位置:document.documentElement.scrollTop = ocument.body.scrollTop = 位置; document.documentElement.scrollLeft = document.body.scrollLeft = 位置;
- 滚动条滚动时,稍微有点跳动是由于各浏览器性能问题造成。如果跳动很大就是在设置元素位置时和滚动条位置之间的判断有问题
居中的广告弹窗:使用固定定位可以实现;此处使用绝对定位+滚动条位置实现
弹窗在可视区居中:距离顶部的距离(整个可视区高度-ad弹窗高度)/2和距离左侧距离(整个可视区宽度-ad弹窗宽度的)/2
<!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 {
height: 200px;
width: 2000px;
border: 1px solid black;
}
#ad {
width: 200px;
height: 200px;
background: black;
color: white;
font: 30px/200px "宋体";
text-align: center;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div id="ad">这是一个广告</div>
<div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div><div>1</div>
<script>
//需求:将广告定位到浏览器正中间。拖动滚动条和缩放窗口时,仍然保持中心位置
{
let ad = document.querySelector("#ad");
//弹窗在可视区:居中:距离顶部的距离(整个可视区高度-ad弹窗高度)/2和距离左侧距离(整个可视区宽度-ad弹窗宽度的)/2
//浏览器可视区宽高
// let windowW = innerWidth;
// let windowH = innerHeight;
//广告弹窗本身宽高
// let adW = ad.offsetWidth;
// let adH = ad.offsetHeight;
let setPos = ()=>{
//设置决定定位位置
let l = (innerWidth-ad.offsetWidth)/2;
let t = (innerHeight-ad.offsetHeight)/2;
//获取滚动条位置:在滚动条滚动时,加上滚动条位置即可居中
let scrollL = document.documentElement.scrollLeft || document.body.scrollLeft;
let scrollT = document.documentElement.scrollTop || document.body.scrollTop;
ad.style.left = l + scrollL + "px";
ad.style.top = t + scrollT + "px";
}
//页面第一次刷新时设置定位
setPos();
//监听到窗口缩放时,需要设置
window.onresize = () =>{
setPos();
};
//监听到滚动条位置发生变化时,需要设置
window.onscroll = () =>{
setPos();
};
}
</script>
</body>
</html>
如果需要解决滚动条移动和缩放窗口时稍许抖动问题,可以加上动画效果:
//监听到窗口缩放时,需要设置
window.onresize = () =>{
ad.style.transition = "1s";
setPos();
};
//监听到滚动条位置发生变化时,需要设置
window.onscroll = () =>{
ad.style.transition = "1s";
setPos();
};
2.location 对象
- - hash
- - hashChange
- - search
- - reload()
- - replace()
2.1location对象概览
- host:主机名/域名+端口
- hostname:主机名/域名+端口。端口默认为80,如果端口不是80就会显示,服务器端设置;
- port:端口号
- href:完整的地址。包括get请求的数据和hash值
- origin:
- pathname:服务器中的项目路径
- protocol:协议,主要有http和https
- hash:
- search:代表get方式提交过来的数据。如:?kkb=开课吧。post提交的数据地址栏获取不到。有hash值,也获取不到
示例:访问https://www.lyblog.net/category/webfront.html,在控制台输入location后:
2.2location对象重点方法解析
- location.href:完整的地址栏信息,既可以获取也可以设置
- location.replace(): 替换掉地址栏信息。和href很像,但使用方法不一样
- location.reload:刷新页面。也可以使用location.href = location.href进行刷新
- location.hash:地址中 # 后面的内容
location.href:完整的地址栏信息,既可以获取也可以设置
<body>
<button>跳转</button>
<script>
{
let btn = document.querySelector("button");
btn.onclick = ()=>{
//获取href信息
console.log(location.href);//file:///E:/StudyFile/kaikeba/works/BOM%E4%B8%93%E9%A2%98/location.href.html
location.href = "https://www.baidu.com/s?wd=开课吧"
};
}
</script>
</body>
location.replace(): 替换掉地址栏信息。和href很像,但使用方法不一样
let btn = document.querySelector("button");
btn.onclick = ()=>{
location.replace("https://www.baidu.com/s?wd=开课吧");
};
location.reload:刷新页面
<body>
<button>刷新</button>
<script>
{
let btn = document.querySelector("button");
btn.onclick = ()=>{
// location.reload();
location.href = location.href;
};
}
</script>
</body>
2.3location.hash路由实现原理
路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。
JS中的hash路由:根据路径决定前端显示的视图。相当于css中的锚点
onhashchange :监听location中hash的变化
vue和react中的hash-router就是根据hash原理实现
需求:页面第一次刷新和#view1时,显示view1;#view2时显示view2;#view3时显示view3
<body>
<a href="#view1">视图1</a>
<a href="#view2">视图2</a>
<a href="#view3">视图3</a>
<div id="view">这是第一个视图</div>
<script>
{
let view = document.querySelector("#view");
let setView = ()=>{
let hash = location.hash;
console.log(hash);
switch(hash){
case "":
case "#view1":
view.innerHTML = '这是第一个视图';
break;
case "#view2":
view.innerHTML = '这是第二个视图';
break;
case "#view3":
view.innerHTML = '这是第三个视图';
break;
default:
view.innerHTML = '这是第一个视图';
}
};
window.onhashchange = setView;
}
3.history 对象
- - back():返回历史记录的上一步
- - forward():返回历史记录的下一步
- - go():跳转到某一步。负数表示回退,整数表示往后。
- - state
- - pushState()
- - popstate
- - history 路由实现原理
3.1 back()/forward()/go():
返回历史记录的上一步,下一步或指定某一步
<a href="history_1.html">视图1</a>
<a href="history_2.html">视图2</a>
<a href="history_3.html">视图3</a>
<br>
<button>跳转到</button>
<input type="text">
<button>上一页</button>
<button>下一页</button>
<div>这个第一页</div>
<script>
{
let btn = document.querySelectorAll("button");
btn[0].onclick = () =>{
let page = document.querySelector("input");
history.go(parseInt(page.value));
};
btn[1].onclick = () =>{
// history.go(-1);
history.back();//上一页
};
btn[2].onclick = () =>{
// history.go(-1);
history.forward();//下一页
};
}
3.2 history对象路由实现原理
- -state
- - pushState()
- - popstate
- - history 路由实现原理
history路由实现原理:
- 必须禁用原来的页面跳转功能;
- 必须配合服务器环境下使用
history.pushState()方法:用于设置对应的切换模板地址。
history.pushState()方法参数:
- 第一个参数 可以为一个对象{ name:val},一般用于传值,并可在window.onpopstate 点击浏览器上 前进后退按钮后进行获取
- 第二个参数 title,基本没有什么实质作用
- 第三个参数 history状态值,即每个url对应的模板地址
window.onpopstate事件:历史记录上下切换事件 - 浏览器上 点击前进后退按钮后生效
使用history路由实现静态页面切换,示例:
<!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>
li {
margin: 10px;
}
</style>
</head>
<body>
<div id="view">
<ul>
<li><a href="/index">首页</a></li>
<li><a href="/about">关于我们</a></li>
<li><a href="/details">详细介绍</a></li>
</ul>
<div id="cont"></div>
</div>
<script>
{
/*
history路由实现原理:
1:必须禁用原来的跳转功能;
2:必须配合服务器环境下使用
*/
let view = document.querySelector("#view");
let ul = document.querySelector("ul");
let allA = document.querySelectorAll("ul a");
let cont = document.querySelector("#cont");
let indexRender = ()=>{
return `
<p>这是首页相关信息</p>
`;
}
let aboutRender = ()=>{
return `
<p>这是关于我们相关信息</p>
`;
}
let detailsRender = ()=>{
return `
<p>这是详细介绍相关信息</p>
`;
}
let matching =()=>{
let path = location.pathname;
console.log(location.pathname);
switch(path){
case "/UnionpayDemo/":
case "/index":
cont.innerHTML = indexRender();
break;
case "/about":
cont.innerHTML = aboutRender();
break;
case "/details":
cont.innerHTML = detailsRender();
break;
}
}
//页面一开始刷新时也要显示默认页面
matching();
allA.forEach(item=>{
item.onclick = function(){
/*
切换对应的模板地址:history.pushState()方法
history.pushState()方法参数
第一个参数 可以为一个对象{ name:val},一般用于传值,并可在window.onpopstate 点击浏览器上 前进后退按钮后进行获取
第二个参数 title,基本没有什么实质作用
第三个参数 history状态值,即每个url对应的模板地址
*/
console.log(item.href);
history.pushState({info:'lmf',age:18},"history路由实现原理",item.href);
matching();
//注意return false阻止浏览器默认事件,只能用于绑定事件不能用于事件监听
return false;
}
});
// 历史记录上下切换事件 - 浏览器上 前进后退按钮
window.onpopstate = function(){
// 获取history传递过来的值
console.log(history.state)
matching();
}
}
</script>
</body>
</html>
由于服务器编码问题导致乱码。但不影响结果。
4. navigator 对象
- - userAgent
- - appName
- - appVersion
4.1navigator对象概览
存储关于设备和浏览器的一些信息。
- appCodeName:返回浏览器的代码名。在所有以 Netscape 代码为基础的浏览器中,它的值是 "Mozilla"。为了兼容起见,在 Microsoft 的浏览器中,它的值也是 "Mozilla"。
- appName:返回浏览器的名称。
- appVersion:返回浏览器的平台和版本信息。
- onLine:返回指明系统是否处于脱机模式的布尔值。
- userAgent:返回由客户机发送服务器的 user-agent 头部的值。
- browserLanguage:返回当前浏览器的语言。
- cookieEnabled:返回指明浏览器中是否启用 cookie 的布尔值。
4.2 navigator的userAgent(**)
判断是否为PC:
function IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
判断设备(是安卓还是苹果(iPad是苹果的一种)):
var ua = navigator.userAgent.toLowerCase();
if (/android|adr/gi.test(ua)) {
// 安卓
}else if(/iPad/gi.test(ua)){
//iPad
}else if(/\(i[^;]+;( U;)? CPU.+Mac OS X/gi.test(ua)){
//苹果
}
判断不同客户端:新浪微博为1,QQ客户端为2,微信低于6.0.2版本为3,高于6.0.2版本为4,其他为0。
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/weibo/i) == "weibo"){
console.log(1);
}else if(ua.indexOf('qq/')!= -1){
console.log(2);
}else if(ua.match(/MicroMessenger/i)=="micromessenger"){
var v_weixin = ua.split('micromessenger')[1];
v_weixin = v_weixin.substring(1,6);
v_weixin = v_weixin.split(' ')[0];
if(v_weixin.split('.').length == 2){
v_weixin = v_weixin + '.0';
}
if(v_weixin < '6.0.2'){
console.log(3);
}else{
console.log(4);
}
}else{
console.log(0);
}
区分各个浏览器:
var ua=navigator.userAgent.toLowerCase();
if(/msie/i.test(ua) && !/opera/.test(ua)){
alert("IE");
return ;
}else if(/firefox/i.test(ua)){
alert("Firefox");
return ;
}else if(/chrome/i.test(ua) && /webkit/i.test(ua) && /mozilla/i.test(ua)){
alert("Chrome");
return ;
}else if(/opera/i.test(ua)){
alert("Opera");
return ;
} else if(/webkit/i.test(ua) &&!(/chrome/i.test(ua) && /webkit/i.test(ua) && /mozilla/i.test(ua))){
alert("Safari");
return ;
}else{
alert("unKnow");
}
5.screen 对象
width 、height:获取的屏幕的宽高