原 八、BOM

作者:汪娇娇

时间:2017年11月18日

BOM提供了很多对象,用于访问浏览器的功能,这些功能与任何网页内容无关。

一、window 对象

BOM的核心对象是window,它表示浏览器的一个实例。在浏览器中,window对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象。

1、全局作用域

全局作用域中声明的变量、函数都会变成window对象的属性和方法。

定义全局变量与在window对象对象上直接定义属性的差别:全局变量不能通过delete操作符删除,而直接在window对象上的定义的属性可以。

2、窗口关系及框架

  • top:top对象始终指向最高(最外)层的框架,也就是浏览器窗口;
  • parent:parent对象始终指向当前框架的直接上层框架(某些情况下,parent有可能等于top);
  • self:它始终指向window。

3、窗口位置

  • screenLeft 和 screenTop:分别用于表示窗口相对于屏幕左边和上边的位置。支持的浏览器:IE、Safari、Opera和Chrome
  • screenX 和 sreenY:同上。支持浏览器:Firefox、Safari和Chrome。Opera里的这两个属性和screenLeft、screenTop属性不对应,所以建议在Opera中不要使用它们。
  • moveTo() 和 moveBy():将窗口精确地移动到一个新位置。这2个方法都接收2个参数,moveTo()接收的是新位置的 x 和 y 坐标值,而moveBy() 接收的是在水平和垂直方向上移动的像素值。 
// screenLeft、screenTop 、screenX、screenY
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;

// moveTo()、moveBy()
window.moveTo(0,0);  //将窗口移动到屏幕左上角
window.moveBy(0,100);  //将窗口向下移动100像素

4、窗口大小

  • innerWidth、innerHeight、outerWidth、outerHeight:outerWidth和outerHeight返回浏览器窗口本身的大小,而innerWidth和innerHeight则表示该容器中页面视图区的大小(减去边框宽度)。在IE、Firefox、Safari、Opera和Chrome中,document.documentElement.clientWidth 和 document.documentElement.clientHeight中保存了页面视口的信息。而在IE6中,这些属性只在标准模式下才有效,在混杂模式下必须用:document.body.clientWidth 和 document.body.clientHeight。
  • resizeTo()、resizeBy():可以调整浏览器窗口的大小。这2个方法都接收2个参数,resizeTo()接收浏览器窗口的新宽度和新高度,而resizeBy() 接收新窗口与原窗口的宽度和高度之差。 
// innerWidth、innerHeight
var pageWidth = window.innerWidth,
    pageHeight = window.innerHeight;

if(typeof pageWidth != "number"){
   if(document.compatMode == "CSS1Compat"){
       pageWidth = document.documentElement.clientWidth;
       pageHeight = document.documentElement.pageHeight;
   }else{
       pageWidth = document.body.clientWidth;
       pageHeight = document.body.pageHeight;
   }
}

// resizeTo()、resizeBy()
window.resizeTo(100,100);  //调整到100 × 100
window.resizeBy(100,50);  //调整到200 × 150

5、导航和打开窗口

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

这个方法可以接收4个参数:要加载的URL、窗口目标、一个特性字符串、一个表示新页面是否取代浏览器历史纪录中当前加载页面的布尔值。

// 等同于<a href="http://www.baidu.com" target="topFrame"></a>
window.open("http://www.baidu.com","topFrame");

第二个参数topFrame也可以是下列任何一个特殊的窗口名称:_self、_parent、_top、_blank。

  • 弹出窗口屏蔽程序

大多数浏览器都内置有弹出窗口屏蔽程序,那么window.open() 很可能会返回null。因此,要想准确地检测出弹出窗口是否被屏蔽,必须检测返回值的同时,将对window.open() 的调用封装在一个try-catch块中,如下所示:

var blocked = false;

try{
    var wroxWin = window.open("http://www.baidu.com", "_blank");
    if (wroxWin == null) {
        blocked = true;
    }
}catch (ex) {
    blocked = true;
}

if (blocked){
    alert("The popup was blocked !");
}

6、间歇调用和超时调用

间歇调用:setInterval()

超时调用:setTimeout()

//经过1s后alert不一定执行(因为JavaScript是一个单线程序的解析器),这段代码是告诉JS再过多久才把当前任务添加到队列中
setTimeout(function(){
   alert("Hello World !");
},1000)

调用setTimeout() 后,该方法会返回一个数值ID,表示超时调用。这个超时调用ID是计划执行代码的唯一标识符,可以通过它来取消超时调用。

// 设置超时调用
var timeoutId = setTimeout(function(){
   alert("Hello World !");
},1000)

// 取消
clearTimeout(timeoutId);

7、系统对话框

alert()、confirm()、prompt()、find()、print()

// alert
alert("Hello World !");

// confirm
if(confirm("Are you sure ?")){
    alert("I'm so glad you're sure. ");
}else{
    alert("I'm sorry to hear you're not sure. ");
}

// prompt
var result = prompt("What is your name? ");
if(result != null){
    alert("Welcome", + result);
}

// print
window.print();

// find
window.find();

二、location 对象

location是最有用的BOM对象之一,它提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。

location既是window对象的属性,也是document对象的属性;换句话说,window.location和document.location引用的是同一个对象。

属性名

例子

说明

hash

"#contents"

返回URL中的hash,如果没有,则返回空字符串

host

"www.baidu.com:80"

返回服务器名称和端口号

hostname

"www.baidu.com"

返回不带端口号的服务器名称

href

"http://www.baidu.com"

返回当前加载页面的完整URL

pathname

"/WilyCDA/"

返回URL中的目录和(或)文件名

port

"8080"

返回URL中指定的端口号,如果不包含,则返回空字符串

protocol

"http:"

返回页面使用的协议

search

"?q=javascript"

返回URL的查询字符串

1、查询字符串参数

function getQueryStringArgs(){

    var qs = (location.search.length > 0 ? location.search.sunstring(1) : "" ),

    args = {},

    items = qs.length ? qs.split("&") : [],

    item = null,

    name = null,

    value = null,

    i = 0,

    len = items.length;

    for( i=0; i < len; i++){
        item = items[i].split("=");
        name = decodeURIComponent(item[0]);
        value = decodeURIComponent(item[1]);

        if(name.length > 1){
            args[name] = value;
        }
    }

    return args;  
}

调用实例:

// 假设查询字符串是 ?q=javascript&num=10

var args = getQueryStringArgs();

alert(args["q"]);  //"javascript"
alert(args["num"]);  //"10"

2、位置操作

  • assign():打开新URL,并在浏览器的历史记录中生成一条记录
//下面这三种方法效果一样

location.assign("http://www.baidu.com");
window.location = "http://www.baidu.com";
location.href("http://www.baidu.com");
  • replace():不会在历史记录中生成一条新记录
  • reload():重新加载当前显示的页面
location.reload(); //重新加载(有可能从缓存中加载)
location.reload(true); //重新加载(从服务器重新加载)

三、navigator 对象

识别客户端浏览器的事实标准。

1、检查插件

对于非IE浏览器,可以引用 plugins 数组来检测插件。该数组包含以下属性:

  • name:插件名字
  • description:插件描述
  • filename:插件文件名
  • length:插件所处理的MIME类型数量
// 检测插件(在IE中无效)
function hasPlugin(name){
    name = name.toLowerCase();
    for(var i = 0; i < navigator.plugins.length; i++){
        if(navigator. plugins [i]. name.toLowerCase().indexOf(name) > -1){
            return true;
        }
    }
    return false;
}

//检测Flash
alert(hasPlugin("Flash"));

//检测QuickTime
alert(hasPlugin("QuickTime"));
// 检测IE中的插件
function hasIEPlugin(name){
    try{
        new ActiveXObject(name);
        return true;
    } catch (ex) {
        return false;
    }
}

// 检测Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));

// 检测QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));
// 检查所有浏览器中的Flash
function hasFlash(){
    var result = hasPlugin("Flash");
    if(!result){
        result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash");
    }
    return result;
}

// 检查所有浏览器中的QuickTime
function hasQuickTime(){
    var result = hasPlugin("QuickTime");
    if(!result){
        result = hasIEPlugin("QuickTime.QuickTime");
    }
    return result;
}

// 检测Flash
alert(hasFlash());

// 检测QuickTime
alert(hasQuickTime());

plugins集合有一个 refresh() 的方法,用于刷新plugins以反应最新安装的插件。

2、处理注册程序

RegisterContentHandler() 和 RegisterProtocolHandler() 。

这两个方法可以让一个站点指明它可以处理特定类型的信息。

// 将一个站点注册为处理RSS源的处理程序
nvigator.RegisterContentHandler("application/rss+xml", "http://www.somereader.com?feed=%s", "Some Reader");

// 将一个应用程序注册默认的邮件客户端(%S 表示最原始的请求)
nvigator.RegisterProtocolHandler("mailto", "http://www.somemailclient.com?cmd=%s", "Some Mail Client");

四、screen对象

availWidth、availHeight、availLeft、availTop、left、top、width、height等。

五、history 对象

  • go():可以在用户的历史记录中任意跳转。
  • back() :后退
  • forward():前进
  • length:保存着历史记录的数量
// 后退一页
history.go(-1);
history.back();

// 前进一页
history.go(1);
history.forward();

六、小结

浏览器对象模型(BOM)以 window对象为依托,表示浏览器窗口以及页面可见区域。同时,,window对象还是 ECMAScript中的 Global 对象,因而所有全局变量和函数都是它的属性,且所有原生的构造函数及其他函数也都存在于它的命名空间下。本章讨论了下列BOM的组成部分。

  • 在使用框架时,每个框架都有自己的 window 对象以及所有原生构造函数及其他函数的副本。每个框架都保存在 frames 集合中,可以通过位置或通过名称来访问。
  • 有一些窗口指针,可以用来引用其他框架,包括父框架。
  • top 对象始终指向最外围的框架,也就是整个浏览器窗口。
  • parent 对象表示包含当前框架的框架,而 self 对象则回指 window。
  • 使用 location 对象可以通过编程方式来访问浏览器的导航系统。设置相应的属性,可以逐段或整体性地修改浏览器的URL。
  • 调用 replace() 方法可以导航到一个新URL,同时该URL会替换浏览器历史记录中当前显示的页面。
  • navigator对象提供了与浏览器有关的信息。到底提供哪些信息,很大程度上取决于用户的浏览器;不过,也有一些公共的属性(如 userAgent )存在于所有浏览器中。

BOM中还有两个对象: screen 和 history,但它们的功能有限。screen对象中保存着与客户端显示器有关的信息,这些信息一般只用于站点分析。history对象为访问浏览器的历史记录开了一个小缝隙,开发人员可以据此判断历史记录的数量,也可以在历史记录中向后或向前导航到任意页面。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏salesforce零基础学习

salesforce lightning零基础学习(二) lightning 知识简单介绍----lightning事件驱动模型

25330
来自专栏前端下午茶

Vue源码阅读 - 文件结构与运行机制

vue已是目前国内前端web端三分天下之一,同时也作为本人主要技术栈之一,在日常使用中知其然也好奇着所以然,另外最近的社区涌现了一大票vue源码阅读类的文章,在...

13330
来自专栏进步博客

解决CSV文件中长数字以科学记数格式保存问题

12120
来自专栏非著名程序员

仿苹果数字键盘以及判断信用卡有效期的Editext

这次带来一个小小的信用卡有效期规则的Editext,额外赠送内置数字键盘的开发 首先来看下需求: 1) 月份数字: λ 数字输入0:后一位数字可输入...

23150
来自专栏偏前端工程师的驿站

前端构建:Less入了个门

一、前言                                说到前端构建怎能缺少CSS预处理器呢!其实CSS的预处理器有很多啦,比较出名的有Scs...

20370
来自专栏CRPER折腾记

Vue折腾记 - (3)写一个不大靠谱的typeahead组件

typeahead在网站中的应用很多..今天跟着我来写一个不大靠谱的typeahead;

8810
来自专栏自由而无用的灵魂的碎碎念

针对plsql developer使用做的三个小设置

1、原来大家在sql窗口写多条sql语句,如果点击“执行”,那么会执行窗口下的所有语句,如果向执行所要的语句,必须选定它。

8520
来自专栏web编程技术分享

eclipse常用快捷键

30360
来自专栏云瓣

深入Redux架构

关于redux 之前写了一篇通过一个demo了解Redux,但对于redux的核心方法没有进行深入剖析,在此重新总结学习,完整的代码看这里。(参考了React ...

29960
来自专栏葡萄城控件技术团队

Silverlight自定义数据绑定控件应该如何处理IEditableObject和IEditableCollectionView对象

最近在一直研究Silverlight下的数据绑定控件,发现有这样两个接口IEditableObject 和IEditableCollectionView,记录一...

20190

扫码关注云+社区

领取腾讯云代金券