本文介绍BOM相关的知识点,介绍的重点在于BOM核心Window对象的成员细节。

BOM简单介绍

我们已经知道JavaScript的范围包括ECMAScript(语言核心) + DOM(文档对象模型) + BOM(浏览器对象模型)

BOM 是 Browser Object Model(浏览器对象模型)的缩写,它提供了独立于内容 而与浏览器窗口进行交互的对象。由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是window,它表示流浏览器的一个实例。BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性,window作为最顶层的对象,BOM中所有的对象都是通过它延伸出来的。

标准化 JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C, 而BOM因为缺乏标准,BOM最初其实是Netscape浏览器标准的一部分,而这也正是各种浏览器不兼容的根源所在。此外需要指出的是,W3C为了把浏览器中JavaScript最基本的部分标准化,已经将BOM的主要方面纳入了HTML5的规范中。

window和全局作用域

在浏览器中,window对象拥有着双重的角色,它既是通过JavaScript访问浏览器窗口的接口,也是ECMAScript规定中的Global全局对象。因此,所有在全局作用域中声明的变量、函数都会自动成为window对象的属性和方法。

全局作用域

> ✧ 定义在全局环境下的变量和函数都会成为 `window` 对象的成员(属性和方法)
> ✧ 编码的时候应该尽可能少的使用全局变量,以避免污染全局环境
> ✧ 没有用var声明的变量会成为全局变量,即 `window` 对象的属性
> ✧ 在编码时`window` 前缀可以被省略,如 `window.console.log()` 通常写成 `console.log()`;

代码示例

  /*01-全局作用域示例*/
console.log(window.age); //undefined
var age = 12;
console.log(age, window.age); //12 12 age自动成为window的属性 console.log(window.arr); //undefined
var arr = [1,2,3,"T"];
console.log(arr == window.arr); //true
arr.push("V");
console.log(window.arr); //[1,2,3,"T","V"]; function sum(a,b) {
return a + b;
}
console.log(sum(1, 2)); //3
console.log(window.sum(1, 3)); //4 /*02-没有使用var声明的变量默认成为全局变量*/
address = "北京市海淀区";
console.log(window.address); //"北京市海淀区"; function f() {
var a = "我是a";
b = "我是b";
} f(); /*调用函数f,执行函数体中的代码*/
//console.log(a); //报错 无法访问变量a 因为a是f函数中的局部变量
console.log(b); //"我是b" b默认成为全局变量
console.log(window.a); //undefined
console.log(window.b); //"我是b" /*03-省略window前缀*/
console.log(window.console == console); //true

因为全局作用域中声明的所有变量都会自动成为window的属性,而实际的开发中代码量可能是巨大的,且项目可能是由很N多人一起维护的,因此应该尽可能的减少全局变量的数量,以防止污染全局环境。

关于这个问题的解决方案可以有两种,一种是根据具体的业务和功能将部分代码封装到匿名函数(闭包)中保持独立性,一种是把很多变量和函数封装到特定的对象中处理。当然,更成熟的方案是使用 模块化 的方式来组织项目和代码结构,其实模块化的开发方式也是使用匿名函数封装的一种变形,在这里我们暂不作具体的展开。

注意 delete 用于删除对象的属性,需注意虽然使用delete关键字可以删除直接定义在 window 上面的属性,但却无法直接删除用 var 声明的全局变量(在严格模式下不能禁止使用 delete 来删除遍历,错误信息为 Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. )。

 /*测试1:使用delete删除对象的属性*/
var obj = {id:"1001"};
console.log(delete obj.id); //true
console.log(obj.id); //undefined /*测试2:使用delete删除全局变量的属性*/
var className = 'H5-1904';
console.log(delete className); //false
console.log(className); //"H5-1904"
console.log(delete window.className); //false
console.log(window.className); //"H5-1904" /*测试3:使用delete删除直接定义在window对象上面的属性*/
window.test = "测试的属性";
console.log(delete window.test); //true
console.log(window.test); //undefined

window核心成员详解

接下来,我将分门别类的讲解浏览器窗口的大小、滚动、导航、打开、弹窗、位置操作、历史记录以及事件处理等内容,所以这些功能都通过 window的核心成员来提供和实现。

window的 location 对象

location对象是window中最有用最重要的对象之一,它提供了与当前窗口中加载的文档有关的信息,而且它非常特殊,它既是window的属性也是document的属性。

location 对象的主要属性

hash     设置/返回从井号 (#) 开始的 URL(锚点)==>哈希值。
href 设置/返回完整的 URL。
search 设置/返回从问号 (?) 开始的 URL(参数部分)。
host 服务器名称和端口号
hostname 服务器名称
pathname URL中的目录和文件名
port 返回指定的端口号,如果没有指定则返回空字符串
protocol 返回网络协议 location 对象的主要方法
assign() 加载新的页面
reload() 重新加载(刷新)
replace(newurl) 使用新的页面来替换当前页面

url的组成http://www.baidu.com:10086/api/reg.php?username=zs&password=123&age=18#123

协议:http

域名:baidu.com

端口:10086 (默认:80)

路径:/api/

参数:username=zs&password=123&age=18

哈希:#123

窗口的主要属性

跨浏览器确定窗口的大小可以使用window的innerWidthinnerHeightouterWidthouterHeight四个属性,它们分别对应的是页面视图容器的宽高和浏览器窗口本身的尺寸。需要注意的是,这几个属性存在兼容性问题,在IE8-中需要通过DOM来获取大小信息。

页面视图容器也称为浏览器的视口(viewport),相比窗口本身来说它不包括工具栏和滚动条。

/*01-获取页面可视区域的大小(宽 | 高)*/
var w =window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth; var h =window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight; /*兼容IE8-
* 如果是标准模式则使用document.documentElement.clientWidth,
* 如果是混杂模式则使用document.body.clientWidth
* */
console.log(w); //877 可视区域的宽度
console.log(h); //410 可视区域的高度 /*02-获取window窗口本身的大小*/
console.log(window.outerWidth); //877 窗口的宽度
console.log(window.outerHeight);//778 窗口的高度 /*03-获取滚动条位置相关的信息*/
console.log(window.scrollX); //水平滚动条滚动过的距离(只读)
console.log(window.scrollY); //垂直滚动条滚动过的距离(只读) /*04-操作滚动的相关方法*/
window.scrollTo(100,100); //指定滚动位置
window.scrollBy(-100,100); //设置基于当前位置的滚动距离

窗口的打开和关闭

语法 window.open([ URL ],[ name ],[ features ],[ replace ])

作用 open()方法用于打开一个新的浏览器窗口或查找一个已命名的窗口。

 /* 作用:打开新的窗口
* 语法:window.open(URL,name,features,replace)
* 参数:
* URL 打开指定页面的URL,没有指定则打开空白窗口。
* name 指定target属性或窗口的名称。
* _blank - 在新的窗口加载页面(默认)
_parent - 在窗口中加载页面
_self - 在当前窗口中加载页面(替换)
_top - URL替换任何可加载的框架集
name - 窗口名称
features 可选的字符串,声明了新窗口要显示的标准浏览器的特征
replace 可选的布尔值,设置浏览历史的处理(true表示替换当前条目,false表示新建条目)
*/
/*01-打开空白窗口*/
window.open(); /*02-打开新的标签页,加载www.wendingding.com站点*/
window.open("http://www.wendingding.com"); /*03-打开新的窗口并控制窗口的外观*/
//toolbar 浏览器工具栏是否显示
//location 是否显示地址字段
//directories 是否添加目录按钮(IE)
//status 是否添加状态栏
//menubar 是否显示菜单栏
//scrollbars 是否显示滚动条
//resizable 窗口是否可调节尺寸
//width 窗口的宽度
//height 窗口的高度
window.open("http://www.wendingding.com","_blank","toolbar=yes, location=yes, " +
"directories=no, status=no, menubar=yes, scrollbars=yes, " +
"resizable=no,width=400, height=400"); /*04-关闭当前窗口*/
window.close(); /*05-该方法用来调出打印窗口*/
window.print();

系统弹框

alert( ) 弹出对话框(确定)

confirm( ) 弹出警告框,返回布尔值(确定&取消)

prompt( ) 弹出输入框,返回消息或 null

  //console.log(alert("确定"));             /*提示框 该方法没有返回值*/
//console.log(confirm("确定删除吗?"));; /*警示窗 确定返回true,取消返回false*/ var res = prompt("好汉请留下尊姓大名","座山雕"); //如果点击了取消那么就返回null
//如果点击了确定那么就返回输入框的内容
console.log(res);

window的 history 对象

window对象中有一个history属性,它本身也是一个对象保存着网页的历史记录(从窗口打开时计算)。出于安全方面的考虑,开发人员无法得知用户浏览过的URL详情,但却可以利用history对象来实现前进和后退的功能。

history对象通过内部的length属性来记录浏览历史的数量,该数据包含了向前和向后的所有浏览记录,默认加载到窗口的第一个页面其history.length的值为0。

go( ) 跳转到任意的浏览历史记录,负数表示后退。

back( ) 后退一页

forward( ) 前进一页

    /*方法演示  下面代码中的window前缀可以省略*/
console.log(window.history.length); //获取历史记录长度
window.history.go(1); //前进1页
window.history.go(-1); //后退1页
window.history.back(); //回退
window.history.forward(); //前进

window的事件补充

onresize 事件会在窗口大小调整的时候被触发。

onscroll 事件在页面滚动条滚动的时候会被触发。

onload 事件会在页面加载完成(HTML+CSS+其它资源)后触发。

前端开发系列031-基础篇之BOM的更多相关文章

  1. 从0到1用react+antd+redux搭建一个开箱即用的企业级管理后台系列(基础篇)

    背景 ​ 最近因为要做一个新的管理后台项目,新公司大部分是用vue写的,技术栈这块也是想切到react上面来,所以,这次从0到1重新搭建一个react项目架子,需要考虑的东西的很多,包括目录结构.代码 ...

  2. 前端开发:css基础知识之盒模型以及浮动布局。

    前端开发:css基础知识之盒模型以及浮动布局 前言 楼主的蛮多朋友最近都在学习html5,他们都会问到同一个问题 浮动是什么东西?  为什么这个浮动没有效果?  这个问题楼主已经回答了n遍.今天则是把 ...

  3. ESP8266开发之旅 基础篇① 走进ESP8266的世界

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  4. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  6. openlayers5-webpack 入门开发系列一初探篇(附源码下载)

    前言 openlayers5-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载 ...

  7. leaflet-webpack 入门开发系列一初探篇(附源码下载)

    前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 w ...

  8. 【Windows10 IoT开发系列】配置篇

    原文:[Windows10 IoT开发系列]配置篇 Windows10 For IoT是Windows 10家族的一个新星,其针对不同平台拥有不同的版本.而其最重要的一个版本是运行在Raspberry ...

  9. ESP8266开发之旅 基础篇④ ESP8266与EEPROM

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  10. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

随机推荐

  1. 创建bean对象的三种方式

    一.使用无参构造方法创建 二.使用静态工厂创建 三.使用实例工厂创建

  2. python读取文件夹内所有图片名称,随机设置为桌面壁纸且把设置后的图片移到其他文件夹内的方法

    关键词:读取文件夹.读取文件.操作系统.设置壁纸.移动文件 预期实现如下几个步骤 1.获取指定文件夹内所有图片名 2.随机取一张图片设置为壁纸 3.设置为壁纸的图片移动到另外一个文件夹中 第一步,获取 ...

  3. win mysql实现主从同步(精简版)

    最近项目要弄读写分离,那首先要实现主从同步啊,网上教程很多,但大多都看得云里雾里,so,有了这个精简版: 主库my.ini添加配置: #数据库ID号, 为1时表示为Master,其中master_id ...

  4. Fortify工具安装以及使用

    ​工具简介: Fortify是一款强大的静态代码扫描分析工具,其发现代码漏洞缺陷的能力十分强悍,主要是将代码经过编译,依托于其强大的内置规则库来发现漏洞的.Fortify 是一个静态的.白盒的软件源代 ...

  5. P10856 【MX-X2-T5】「Cfz Round 4」Xor-Forces题解

    题意: 给定一个长度为 \(n=2^k\) 的数组 \(a\),下标从 \(0\) 开始,维护 \(m\) 次操作: 给定 \(x\),设数列 \(a'\) 满足 \(a'_i=a_{i\oplus ...

  6. SQL 强化练习 (二)

    继续 sql 搞起来, 面向过程来弄, 重点是分析的思路, 涉及的的 left join, inner join, group by +_ having, case when ... 等场景, 也是比 ...

  7. 前n项结尾0的个数

    题目链接:K-卡特兰数_2023河南萌新联赛第(二)场:河南工业大学 (nowcoder.com) 一开始想到和阶乘末尾0的个数一样的题目,但有点不同,根据公式,一开始的重点完全在公式上了,因为前几项 ...

  8. 第6讲、全面拆解Encoder、Decoder内部模块

    全面拆解 Transformer 架构:Encoder.Decoder 内部模块解析(附流程图小测验) 关键词:Transformer.Encoder.Decoder.Self-Attention.M ...

  9. Java子类上加lombock注解@Data或者@ToString,日志中不包括父类的属性

    问题描述:Java子类上加lombock注解@Data或者@ToString,在翻阅日志的时候,发现不打印父类的属性. 问题分析:@Data在编译时会自动为实体类添加setter.getter和toS ...

  10. Spring注解之@FeignClient注解使用方法

    声明接口时在代码中通过@Resource注入容器之后即可使用.@FeignClient注解的常用属性如下: value/name:value和name的作用一样,用于指定FeignClient的名称: ...