JavaScript高级程序设计学习8_BOM

1、窗口位置

IE、Safari、Opera和Chrome都提供了screenLeft和screenTop属性,Firefox则提供了screenX和screenY属性,Safari和Chrome同时也支持这两个属性,使用下列代码可ku跨浏览器取浏览器窗口的位置:

let leftPos = (typeof window.screenLeft == 'number')? window.screenLeft:window.screenX;
let topPos = (typeof window.screenTop == 'number')? window.screenTop:window.screenTop;

2、窗口大小

跨浏览器确定窗口的大小不是一件简单的事。IE、Safari、Firefox、Opera和Chrome均提供了4个属性:innerWidth、innerHeight、outerHeight和outerWidth。在IE9+、Safari和Firefox中,outerHeight和outerWidth返回浏览器本身的尺寸。在Opera中,这两个属性表示页面视图容器(指Opera中单个标签页对应的浏览器窗口)的大小。而innerWidth、innerHeight则表示该容器中页面视图区的大小(减去边框宽度)。在Chrome中,innerWidth、innerHeight、outerHeight和outerWidth返回相同的值,即视口大小而非浏览器窗口大小。

通过DOM,在IE、Safari、Firefox、Opera和Chrome中,document.documentElement.clientWidth和document.documentElement.clientHeight中就保存了视口的信息(标准模式);如果是混杂模式就必须通过document.body.clientWidth和document.body.clientHeight来获取,虽最终无法确定浏览器的大小名单可以取到视口大小,如下:

let pageWidth = window.innerWidth,
pageHeight = window.innerHeight;

if(typeof pageWidth != "number"){
  if(document.compatMode == "CSS1Compat")//检查是否处于标准模式
  {
    pageWidth = window.documentElement.clientWidth,
    pageHeight = window.documentElement.clientHeight;
  }
  else{
    pageWidth = window.body.clientWidth,
    pageHeight = window.body.clientHeight;
  }
}

3、超时调用和间歇调用

setTimeout()和setInterval(),常用、不做赘述

4、location对象

location是最有用的BOM对象之一。它提供了与当前窗口中加载的文档有关的信息、还提供了一些导航功能。注意:window.location和document.location引用的是同一个对象,下面是location的所有属性: 

属性名 例子 说明
hash "#contents" 返回URL中的hash(#号后跟0或多个字符),如果URL不包含散列,则返回空字符串
host "www.wrox.com:80" 返回服务器名称和端口号(if exist)
hostname "www.wrox.com" 返回服务器名称
href "http://www.wrox.com" 返回当前加载页面的完整URL。而location对象的toString()也是返回这个值
pathname "/WileyCDA" 返回URL中的目录和(或)文件名
port "8080" 返回URL中指定的端口号(if exist),否则返回空字符
protocol "http:" 返回页面使用的协议。通常是http:或https:
search "?q=javascript" 返回URL的查询字符串。以问号开头

4_1、查询字符串参数

虽然search返回所有内容,但没有办法逐个访问每个参数,可创建函数返回包含所有参数的一个对象:

扫描二维码关注公众号,回复: 3676119 查看本文章
function getQueryStringArgs(){
  let query = (location.search.length > 0 ? location.search.substring(0) : ""),//获取字符串并去掉问号
  args = {},//保存数据的对象
  //获得每一项
  items = query.length ? query.split("&") : [],
  item = null,
  name = null,
  value = null;

  for(let i=0,len=items.length;i<len;i++){
    item = items[i].split("=");
    name = decodeURIComponent(item[0]);
    value = decodeURIComponent(item[1]);
    if(name.length) args[name] = value;
  }

  return args;
}

4_2位置操作

使用hash、search、hostname、pathname和port属性设置新值来改变URL,页面都会以新URL重新加载,hash除外。

当使用以上方法修改URL后,浏览器会生成一条历史纪录,用户点击后退会导航到前一个页面,如要禁止这种行为,可使用replace()方法。如不重新输入完整的URL,则无法返回前一页面

5、navigator对象

已经成为识别浏览器的事实标准。以下是部分属性或方法:

5_1检测插件

检测浏览器中是否安装了特定的插件是一种最常见的检测例程。对于非 IE 浏览器,可以使用plugins 数组来达到这个目的。该数组中的每一项都包含下列属性。
name:插件的名字。
description:插件的描述。
filename:插件的文件名。
length:插件所处理的 MIME 类型数量。

检测插件(在IE中无效):

function hasPlugin(name){
  name = name.toLowerCase();
  for(let i=0;i<navigator.plugins.length;i++){
    if(navigator.plugins[i].name.toLowerCase().indexOf(name) > -1){
      return true;
    }
  }
}

这个 hasPlugin()函数接受一个参数:要检测的插件名。第一步是将传入的名称转换为小写形式,以便于比较。然后,迭代 plugins 数组,通过 indexOf()检测每个 name 属性,以确定传入的名称是否出现在字符串的某个地方。

检测IE插件

function hasIEPlugin(name){
  try{
    new ActiveXObject(name);
    return true;
  }
  catch(ex){
    return false;
  }
}

在 IE 中检测插件的唯一方式就是使用专有的 ActiveXObject 类型,并尝试创建一个特定插件的实例。 IE 是以 COM 对象的方式实现插件的,而 COM 对象使用唯一标识符来标识。因此,要想检查特定的插件,就必须知道其 COM 标识符。在函数内部,首先会尝试创建一个 COM 对象的实例。之所以要在 try-catch 语句中进行实例化,是因为创建未知 COM 对象会导致抛出错误。这样,如果实例化成功,则函数返回 true;否则,如果抛出了错误,则执行 catch块,结果就会返回 false。

鉴于检测这两种插件的方法差别太大,因此典型的做法是针对每个插件分别创建检测函数,而不是使用前面介绍的通用检测方法。来看下面的例子:

//检测flash插件
function hasFlash(){
  let res = hasPlugin("Flash");
  if(!res) res = hasIEPlugin("ShockwaveFlash.ShockwaveFlash");

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

  return res;
}

5_2注册处理程序

Firefox 2 为 navigator 对象新增了 registerContentHandler()和 registerProtocolHandler()方法(这两个方法是在 HTML5 中定义的,相关内容将在第 22 章讨论)。这两个方法可以让一个站点指明它可以处理特定类型的信息。随着 RSS 阅读器和在线电子邮件程序的兴起,注册处理程序就为像使用桌面应用程序一样默认使用这些在线应用程序提供了一种方式。

其中, registerContentHandler()方法接收三个参数:要处理的 MIME 类型、可以处理该 MIME类型的页面的 URL 以及应用程序的名称。举个例子,要将一个站点注册为处理 RSS 源的处理程序,可以使用如下代码:

navigator.registerContentHandler("application/rss+xml","http://www.somereader.com?feed=%s", "Some Reader");

第一个参数是 RSS 源的 MIME 类型。第二个参数是应该接收 RSS 源 URL 的 URL,其中的%s 表示RSS 源 URL,由浏览器自动插入。当下一次请求 RSS 源时,浏览器就会打开指定的 URL,而相应的Web 应用程序将以适当方式来处理该请求。

类似的调用方式也适用于 registerProtocolHandler()方法,它也接收三个参数:要处理的协议(例如, mailto 或 ftp)、处理该协议的页面的 URL 和应用程序的名称。
6、history对象

使用 go()方法可以在用户的历史记录中任意跳转,可以向后也可以向前。这个方法接受一个参数,表示向后或向前跳转的页面数的一个整数值。负数表示向后跳转(类似于单击浏览器的“后退”按钮),正数表示向前跳转(类似于单击浏览器的“前进”按钮)。
 

//后退一页
history.go(-1);
//前进一页
history.go(1);
//前进两页
history.go(2);

也可以给 go()方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置——可能后退,也可能前进,具体要看哪个位置最近。如果历史记录中不包含该字符串,那么这个方法什么也不做,例如:
 

//跳转到最近的 wrox.com 页面
history.go("wrox.com");
//跳转到最近的 nczonline.net 页面
history.go("nczonline.net");

另外,还可以使用两个简写方法 back()和 forward()来代替 go()。顾名思义,这两个方法可以模仿浏览器的“后退”和“前进”按钮。
除了上述几个方法外, history 对象还有一个 length 属性,保存着历史记录的数量。这个数量包括所有历史记录,即所有向后和向前的记录。对于加载到窗口、标签页或框架中的第一个页面而言,history.length 等于 0。通过像下面这样测试该属性的值,可以确定用户是否一开始就打开了你的页面。

if (history.length == 0){
//这应该是用户打开窗口后的第一个页面
}


 

猜你喜欢

转载自blog.csdn.net/kl_123456/article/details/83240096