javascript之有趣的【BOM】深入学习

简介: 本文参考javascript高级程序设计(第三版)并实践后,根据自己的理解发布。文章颇多,认真看完,会有不少的收获。发文不易,喜欢请点赞,转发注明出处,谢谢。

Bom知识不难,就是东西比较多,耐心理解此篇文章,会让你收获满满。相信自己,认真看完。`

BOM(全称:BrowserObjectModel)浏览器模型

有很多小白同学一听到Bom这个词,瞬间晕倒,根本不懂到底是什么,看以上的全称来翻译,就是浏览器中的东西,我们前端浏览器的主要方式在开发中来讲,核心就是window。很多同学还听过一个词叫Dom,初学者来讲,这两个很容易让人有“跳楼”的想法,其实学好了这两个,js中也就明白了一半的知识。

先说说这两个的区别,学过html的同学都知道,html主要是使用标签,标签在页面中其实就是以节点的方式存在的,比如各种嵌套,就是分了很多的标签节点,然后才能开发出想要的布局页面。那么Dom其实就是在用js控制这些标签节点,然后操作各种事情。比如用js创建一个a标签,就可以说创建了一个节点;再或者,用js写出a标签的样式,就可以说控制了节点的样式。完全可以这样理解,但心里要明白,这个标签是js创建出来的,js控制了Dom节点,而非html写出来的,两者是有本质上的区别。那么Bom是来操作浏览器窗口的,比如你alert出一个弹窗,就是在操作Bom,你打开一个新的窗口,也是在操作Bom。所以理解为Bom是操作浏览器window的,这样两者的区别就很显然了。

--window对象和全局作用域--

bom的核心对象是window,它表示浏览器的一个实例。在浏览器中,window对象有双重角色,即是javascript访问浏览器窗口的一个接口,又是ECMAscript规定的Global(全局)对象。因此所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法。如:

var name = 'xiaoming';
function lookName(){
  alert(this.name);
}

console.log(window.name);  //xiaoming
lookName();                //xiaoming
window.lookName();         //xiaoming

从上看出,我们在全局作用域下定义的name,被归在了window对象下,所以可以通过window.name访问,也可以用通过window.lookName()访问函数lookName()。由于是全局作用域,所以this指向了window对象,那么this.name自然也能访问到。

delete操作符

️注意:全局定义的属性不能用delete操作符删除,在window对象上直接定义的属性可以。

var name1 = 'xiaoming';  // 全局定义name1
window.name2 = 'xiaoli'; // 在window上定义name2
console.log(delete window.name1);   // 由于全局定义的不能用delete删除,所以会返回false
console.log(delete window.name2);   // window上的可以被delete删除,会返回true

--window窗口--

窗口位置:

在各个浏览器当中,IE、Safari、Opera、Chrome 都提供了位置属性:screenLeftscreenTop
分别表示:“浏览器窗口相对于屏幕左边和上边的位置”。
但是火狐 (firefox) 却提供了不同的属性:screenXscreenY来表示上述位置。
更有趣的是欧朋浏览器(Opera),四个属性都提供,但screenX、screenY 和 screenLeft、screenTop属性却不对应,所以不建议在Opera中使用。

我们可以用自己的电脑试着打印一下你的窗口位置(用Chrome)举例:

var left = window.screenLeft;
var top = window.screenTop;
console.log(left);
console.log(top);

但是这个案例并不能跨浏览器兼容,因为刚才提到过,firefox不支持screenLeftscreenTop,所以我们要跨浏览器兼容,需要做个判断:

var left = (typeof window.screenLeft == 'number') ? window.screenLeft : window.screenX
var top = (typeof window.screenTop == 'number') ? window.screenTop : window.screenY

这样使用一个三目运算就可以兼容firefox来获取浏览器窗口的位置。

窗口大小:

如果需要跨浏览器兼容,来确定一个窗口的大小也略有不同。

IE9+、firefox、Safari、Opera、Chrome都提供了4个属性: innerHeightinnerWidthouterHeightouterWidth
这四个属性均可以返回浏览器窗口大小,不过略有不同:

IE9+、firefox、Safari中,outerHeightouterWidth返回浏览器窗口本身的尺寸。
Opera、Chrome中,innerHeightinnerWidth表示窗口容器的大小;outerHeightouterWidth表示的是视图区域的大小。

image

IE、firefox、Safari、Opera、Chrome中,有两个相同的方法均提供了页面可视窗口的大小,分别为:

document.documentElement.clientHeight // 视图区域的高度
document.documentElement.clientWidth // 视图区域的宽度

上述图片的视图区域宽高,就是用此方法打印出来的。
不过,这两个方法必须要在标准模式css1Compat下才有效;混杂模式BackCompat下需要通过下边方法才能有效获取宽高信息:

document.body.clientHeight // 视图区域的高度
document.body.clientWidth // 视图区域的宽度

两种模式我们可以用console.log(document.compatMode == "CSS1Compat" ? "当前处于标准模式" : "当前处于混杂模式")来判断,现在目前几乎都是标准模式了。(如果不清楚两种模式的区别,推荐一篇简书中的文章:https://www.jianshu.com/p/4aa37da38b81 ,看起来还不错。)

所以,要跨模式获取可视区域的窗口大小,需要进行判断当前的模式:

// 判断方法:document.compatMode

if(document.compatMode == 'css1Compat'){
  var h = document.documentElement.clientHeight
  var w = document.documentElement.clientWidth 
}else{
  var h = document.body.clientHeight
  var w = document.body.clientWidth 
}

console.log(h)
console.log(w)

// 这样就获取到了当前可视区域的大小

当然,移动端开发也有窗口的大小,如果你沉迷于技术上的钻研,推荐一位移动开发咨询师写的文章:https://quirksmode.org/mobile/viewports2.html 全英文版,如果你的英语不好,可以使用浏览器编译出中文,也能理解到大概的含义。

--导航和打开窗口--window.open()

window.open()方法即可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。

window.open()可接收4个参数:1.url地址 2.窗口目标target 3.窗口设置的字符串 4.取代当前页面的布尔值,分别说一下:`

url地址:就是要加载的浏览器地址。
窗口目标:类似与a标签中的target属性。如果当前有与target相同的窗口,则会在当前窗口加载url。当然,我们也可以传递特殊的名称,例如经常见到的 _blank_top_self_parent
窗口设置的字符串:设置这个的前提是我们加载的url就跳转到一个新的窗口,而不是在当前窗口加载,那么这个参数就很有趣了。我们可以随意设置新窗口的大小,和弹出的位置。如设置宽500,高500的正方形窗口,也可以设置窗口上边坐标与左边的坐标。但要记住,这个参数是以字符串的形式体现的。我们以博主的博客地址https://yq.aliyun.com/u/villin举例:

window.open('https://yq.aliyun.com/u/villin','_blank','width=500,height=500,top=100,left=100')

可以复制这个代码到你的浏览器,会看到弹出一个博客窗口,并且窗口宽高为500,位于屏幕下移100像素,左移100像素。
同时我们还可以通过resizeTo()moveTo()两个方法再次操作新打开窗口的大小和位置,也可以通过close()方法关闭窗口:

var winURL = window.open('https://yq.aliyun.com/u/villin','_blank','width=500,height=500,top=100,left=100');
// 再次调整大小
winURL.resizeTo(500,300);  // resizeTo()接收两个参数,一个是宽度,一个是高度,当窗口打开时,再次调整为宽500px,高300px。
// 再次移动位置
winURL.moveTo(200,200);    // moveTo()接收两个参数,一个是距屏幕top的距离,一个是距屏幕left的距离。
// 3s后关闭窗口
setTimeout(() => {
  winURL.close()
},3000)                    // setTimeout方法:等待一定时间后才开始执行某个任务,两个参数,第一个是方法,第二个是等待时间。

当然,这个参数不仅仅只有这四个属性,还有location,menubar,resizable,scrollbars,toolbar等等。都代表着窗口所显示的菜单栏或其他状态栏,不过目前用到的也比较少,因为每个浏览器兼容性并不一致。
取代当前页面的布尔值:这个参数只有在不打开新的窗口下使用,使用当前页面的浏览历史记录,然后打开新的浏览页面。

--超时调用和间歇调用--setTimeout()/setInterval()

setTimeout()超时调用:等待特定时间后,执行某个方法。两个参数,一个是要执行的代码方法,一个是要等待执行的时间(毫秒mm):

setTimeout(function(){
alert('hello,world')
},2000) // 等待2秒后,弹出hello,world

setTimeout(()=>{
alert('hello,world')
},2000) // 也可以使用箭头函数

setTimeout("alert('hello,world')") // 也可以直接写成字符串方法,不过本方法不推荐使用。

```setInterval()```**间歇调用:**```每间隔一段时间后,都执行某个方法```。两个参数,一个是要执行的代码方法,一个是要等待执行的时间(毫秒mm):

间歇调用与超时调用的方法一样,就是间歇调用是重复不断的执行某个方法,所以可能会某个执行程序还没执行完,就再次的调用了该方法,一般再我们开发中,不到不得已不建议用这个方法。要是用此方法,那么要在页面关闭前,一定要用```clearInterval()```清空这个方法,防止报错:

console.log('hello,world')
},1000) // 每隔一秒就打印一次hello,world

clearInterval(id) // 在页面执行后,记得清空这个方法



**--系统对话框--**

浏览器通过三种对话框方式向用户展示消息:
```1.alert() 带有一个确认按钮的弹出框```  
```2.confirm() 带有一个确认按钮和一个取消按钮的弹出框```  
```3.prompt() 带有输入框的对话弹出框,两个参数:一个是提示信息,一个是输入框默认文本```  

alert()代码:

alert('请输入您的昵称')

显示如下:
![image](https://yqfile.alicdn.com/77c4e3f4cefc7ea752eb7f9275a75a5c80aafb9e.png)

confirm()代码:

var con = confirm('您输入的昵称为:villin')
if(con){
console.log('用户点击了确定')
// 在此可以写确定后的执行代码
}else{
console.log('用户点击了取消')
// 在此可以写取消后的执行代码
}
// 这样可以得到用户输入的返回值,记住,在chrome中,var后边定义的变量不能为name,本人尝试后得到的结果不准。


显示如下:
![image](https://yqfile.alicdn.com/474524aa61c0b2f905a858379cf17179a8be63a9.png)

prompt()代码:

var con = prompt('您输入名字','villin')
if(con){
console.log('用户点击了确定')
// 在此可以写确定后的执行代码
}else{
console.log('用户点击了取消')
// 在此可以写取消后的执行代码
}

显示如下:
![image](https://yqfile.alicdn.com/38a71a7ce328ee2c8b6f8ca8eaa76d6829c52f77.png)

```这种对话框也很有趣,有兴趣的,可以做一个反复弹出的对话框,恶搞你的朋友,可以练习一下。```


**--location对象--**```重要``````重要``````重要```

```location```对象对于Bom来讲,是最有用的对象之一,它提供了当前窗口中加载的文档有关的信息,还提供了一些导航功能。
```location```对象即是window对象的属性,又是document对象的属性。可以说```window.location```和```document.location```引用的是同一个对象。

**location中提供了一些属性:**

hash : 返回url中的hash(#号后边的参数),如果url不包含散列,则返回空字符串。如:"#villin"
host : 返回服务器名称和端口号(如果有端口号的话会返回)。如:“www.villin.com:8080”
hostname : 返回不带端口号的服务器名称。如:“www.villin.com”
href : 返回当前加载页面的完整url。
pathname : 返回url的目录文件名或文件路径。
port : 返回url中指定的端口号。
protocol : 返回页面使用的协议,“http”或“https”。
search : 返回url的查询字符串,这个字符串以“?”开头。


```举例:(每次修改属性后,页面都会重新加载,hash除外)```

假设原地址:www.villin.com/name/

1.添加一个hash地址:
location.hash = "#aaa" 改变后: www.villin.com/home/#aaa

2.添加一个搜索条件:
location.search = "?q=html" 改变后: www.villin.com/home/?q=html

3.将服务器名称修改为 www.abc.com ,后边home路径不变:
location.hostname = "www.abc.com" 改变后: www.abc.com/home/

4.修改原文件路径为/name:
location.pathname = "name" 改变后:www.villin.com/name/

5.添加一个8080端口号:
location.port = 8080 改变后:www.villin.com:8080/name/

打开一个新的页面的方法:

```window.location(www.baidu.com)```
```location.href(www.baidu.com)```
```location.assign(www.baidu.com)```
```location.replace(www.baidu.com)```

️这几种方法都可以跳转到新的页面,目前常用的是```location.href()```方法。修改url后都会生成一条新的记录,因此用户可以通过浏览器单击“后退”按钮,返回到前一个页面,若想禁用后退按钮,使用```location.replace()```方法,即可禁用后退按钮。

与其相关的方法还有一个```location.reload()```,此方法可以重新刷新当前页面。不过值得注意的是,这个方法会根据最有效的方式刷新页面,如果页面自上一次请求以来没有改变过,页面就会从浏览器缓存中重新加载。如果要强制从服务器中重新加载,传递一个参数true即可。```location.reload(true) // 从服务器重新加载```

**--history对象--**
```保存着用户浏览页面的历史记录```

简单介绍几个常见方法:

```history.go(-1) // 后退一页```
```history.go(1) // 前进一页```
```history.go(2) // 前进两页```
```history.go(0) // 重新加载当前页```

**--navigator对象--**
**--screen对象--**
由于window中以上两个个对象并不常用,在这里不做讲解。若有需要,我们可以自己去查阅相关资料。```navigator```对象,我们可以自己在代码中打印一下```console.log(window.navigator)```,自己可以扩展多了解一下浏览器的其他属性。

weChat:VillinWeChat

欢迎提出宝贵意见







目录
相关文章
|
1月前
|
JavaScript 前端开发 开发者
VUE 开发——Node.js学习(一)
VUE 开发——Node.js学习(一)
51 3
|
2月前
|
JavaScript
ES6学习(9)js中的new实现
ES6学习(9)js中的new实现
|
2天前
|
缓存 JavaScript UED
js中BOM中的方法
【10月更文挑战第31天】
|
27天前
|
JavaScript
js学习--制作猜数字
js学习--制作猜数字
35 4
js学习--制作猜数字
|
26天前
|
JavaScript
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
这篇文章介绍了如何将webpack的配置文件分离成开发环境和生产环境的配置文件,以提高打包效率。
42 1
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
|
2月前
|
算法 JavaScript 前端开发
第一个算法项目 | JS实现并查集迷宫算法Demo学习
本文是关于使用JavaScript实现并查集迷宫算法的中国象棋demo的学习记录,包括项目运行方法、知识点梳理、代码赏析以及相关CSS样式表文件的介绍。
第一个算法项目 | JS实现并查集迷宫算法Demo学习
|
2月前
|
JavaScript 前端开发 API
紧跟月影大佬的步伐,一起来学习如何写好JS(上)
该文章跟随月影老师的指导,探讨了编写优质JavaScript代码的三大原则:各司其职、组件封装与过程抽象,通过具体示例讲解了如何在实际开发中应用这些原则以提高代码质量和可维护性。
紧跟月影大佬的步伐,一起来学习如何写好JS(上)
|
27天前
|
JavaScript
js学习--制作选项卡
js学习--制作选项卡
35 4
|
26天前
|
JavaScript
js学习--商品列表商品详情
js学习--商品列表商品详情
14 2
|
26天前
|
JavaScript
js学习--九宫格抽奖
js学习--九宫格抽奖
15 2