08.JavaScript BOM

BOM

window对象

全局作用域

window对象同时扮演着ECMAScript中Global对象的角色,因此所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法

var age = 29;
function sayAge(){
    alert(this.age);
}

alert(window.age);      //29
sayAge();               //29
window.sayAge();        //29
  • 全局变量不能通过delete操作符删除,而直接在window对象上的定义的属性可以;
  • 尝试访问未声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能未声明的变量是否存在
var age = 29;
window.color = "red";

//在IE < 9 时抛出错误,在其他所有浏览器中都返回false 
delete window.age;

//在IE < 9 时抛出错误,在其他所有浏览器中都返回true
delete window.color; //returns true

alert(window.age);   //29
alert(window.color); //undefined

//这里会抛出错误,因为oldValue未定义
var newValue = oldValue;

//这里不会抛出错误,因为这是一次属性查询
//newValue的值是undefined
var newValue = window.oldValue;
窗口关系及框架

如果页面中包含框架,则每个框架都拥有自己的window对象,并且保存在frames集合中。在frames集合中,可以通过数值索引(从0开始,从左至右,从上到下)或者框架名称来访问相应的window对象。每个window对象都有一个name属性,其中包含框架的名称

window对象指向的都是那个框架的特定实例

windows对象里面包含三个对象

  • top
    • 始终指向最高(最外)层的框架,也就是浏览器窗口
    • 使用它可以确保在一个框架中正确地访问另一个框架
  • parent
    • 始终指向当前框架的直接上层框架。在某些情况下,parent有可能等于top;但在没有框架的情况下,parent一定等于top(此时它们都等于window
  • self
    • 始终指向window
窗口位置

IE、Safari、Opera和Chrome都提供了screenLeftscreenTop属性,分别用于表示窗口相对于屏幕左边和上边的位置。Firefox则在screenXscreenY属性中提供相同的窗口位置信息,Safari和Chrome也同时支持这两个属性。Opera虽然也支持screenXscreenY属性,但与screenLeftscreenTop属性并不对应,因此建议大家不要在Opera中使用它们

使用下列代码可以跨浏览器取得窗口左边和上边的位置。

var leftPos = (typeof window.screenLeft == "number") ?
                  window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ?
                  window.screenTop : window.screenY;

这个例子运用二元操作符首先确定screenLeftscreenTop属性是否存在,如果是(在IE、Safari、Opera和Chrome中),则取得这两个属性的值。如果不存在(在Firefox中),则取得screenXscreenY的值

在IE、Opera和Chrome中,screenLeft和screenTop中保存的是从屏幕左边和上边到由window对象表示的页面可见区域的距离。换句话说,如果window对象是最外层对象,而且浏览器窗口紧贴屏幕最上端——即y轴坐标为0,那么screenTop的值就是位于页面可见区域上方的浏览器工具栏的像素高度。但是,在Firefox和Safari中,screenYscreenTop中保存的是整个浏览器窗口相对于屏幕的坐标值,即在窗口的y轴坐标为0时返回0。

  • 使用moveTo()moveBy()方法倒是有可能将窗口精确地移动到一个新位置。

    • 这两个方法都接收两个参数,

    • moveTo()接收的是新位置的xy坐标值

    • moveBy()接收的是在水平和垂直方向上移动的像素数

    • //将窗口移动到屏幕左上角
      window.moveTo(0,0);
      
      //将窗向下移动100像素
      window.moveBy(0,100);
      
      //将窗口移动到(200,300)
      window.moveTo(200,300);
      
      //将窗口向左移动50像素
      window.moveBy(-50,0);
      
    • 这两个方法都不适用于框架,只能对最外层的window对象使用

窗口大小

IE9+、Firefox、Safari、Opera和Chrome均为此提供了4个属性:innerWidthinnerHeightouterWidthouterHeight。在IE9+、Safari和Firefox中,outerWidthouterHeight返回浏览器窗口本身的尺寸(无论是从最外层的window对象还是从某个框架访问)。在Opera中,这两个属性的值表示页面视图容器1的大小。而innerWidthinnerHeight则表示该容器中页面视图区的大小(减去边框宽度)。在Chrome中,outerWidthouterHeightinnerWidthinnerHeight返回相同的值,即视口(viewport)大小而非浏览器窗口大小

在IE、Firefox、Safari、Opera和Chrome中,document.documentElement.clientWidthdocument.documentElement.clientHeight中保存了页面视口的信息。在IE6中,这些属性必须在标准模式下才有效;如果是混杂模式,就必须通过document.body.clientWidthdocument.body. clientHeight取得相同信息。而对于混杂模式下的Chrome,则无论通过document.documentElement还是document.body中的clientWidthclientHeight属性,都可以取得视口的大小。

对于移动设备,window.innerWidthwindow.innerHeight保存着可见视口,也就是屏幕上可见页面区域的大小。移动IE浏览器不支持这些属性,但通过document.documentElement.clientWidthdocument.documentElement.clientHeihgt提供了相同的信息。随着页面的缩放,这些值也会相应变化。

在其他移动浏览器中,document.documentElement度量的是布局视口,即渲染后页面的实际大小(与可见视口不同,可见视口只是整个页面中的一小部分)。移动IE浏览器把布局视口的信息保存在document.body.clientWidthdocument.body.clientHeight中。这些值不会随着页面缩放变化。

  • 使用resizeTo()resizeBy()方法可以调整浏览器窗口的大小。

    • 这两个方法都接收两个参数,

    • 其中resizeTo()接收浏览器窗口的新宽度和新高度,

    • resizeBy()接收新窗口与原窗口的宽度和高度之差

    • //调整到100×100
      window.resizeTo(100, 100);
      
      //调整到200×150
      window.resizeBy(100, 50);
      
      //调整到 300×300
      window.resizeTo(300, 300);
      
    • 这两个方法同样不适用于框架,而只能对最外层的window对象使用。

导航和打开窗口
  • window.open()方法
    • 既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口
    • 这个方法可以接收4个参数:要加载的URL、窗口目标、一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值
    • 通常只须传递第一个参数,最后一个参数只在不打开新窗口的情况下使用。
  1. 弹出窗口
  • 如果给window.open()传递的第二个参数并不是一个已经存在的窗口或框架,那么该方法就会根据在第三个参数位置上传入的字符串创建一个新窗口或新标签页。

  • 如果没有传入第三个参数,那么就会打开一个带有全部默认设置(工具栏、地址栏和状态栏等)的新浏览器窗口(或者打开一个新标签页——根据浏览器设置)。

  • 在不打开新窗口的情况下,会忽略第三个参数。

  • 第三个参数是一个逗号分隔的设置字符串,表示在新窗口中都显示哪些特性。下表列出了可以出现在这个字符串中的设置选项。

  • 设  置说  明
    fullscreenyesno表示浏览器窗口是否最大化。仅限IE
    height数值表示新窗口的高度。不能小于100
    left数值表示新窗口的左坐标。不能是负值
    locationyesno表示是否在浏览器窗口中显示地址栏。不同浏览器的默认值不同。如果设置为no,地址栏可能会隐藏,也可能会被禁用(取决于浏览器)
    menubaryesno表示是否在浏览器窗口中显示菜单栏。默认值为no
    resizableyesno表示是否可以通过拖动浏览器窗口的边框改变其大小。默认值为no
    scrollbarsyesno表示如果内容在视口中显示不下,是否允许滚动。默认值为no
    statusyesno表示是否在浏览器窗口中显示状态栏。默认值为no
    toolbaryesno表示是否在浏览器窗口中显示工具栏。默认值为no
    top数值表示新窗口的上坐标。不能是负值
    width数值表示新窗口的宽度。不能小于100
  • window.open("http://www.wrox.com/","wroxWindow",
                "height=400,width=400,top=10,left=10,resizable=yes");
    

    这行代码会打开一个新的可以调整大小的窗口,窗口初始大小为400×400像素,并且距屏幕上沿和左边各10像素。

  • 调用close()方法还可以关闭新打开的窗口

    • 这个方法仅适用于通过window.open()打开的弹出窗口
  • 新创建的window对象有一个opener属性,其中保存着打开它的原始窗口对象。这个属性只在弹出窗口中的最外层window对象(top)中有定义,而且指向调用window.open()的窗口或框架

    var wroxWin = window.open("http://www.wrox.com/","wroxWindow",
                              "height=400,width=400,top=10,left=10,resizable=yes");
    
    alert(wroxWin.opener == window);   //true
    
  • 有些浏览器(如IE8和Chrome)会在独立的进程中运行每个标签页。当一个标签页打开另一个标签页时,如果两个window对象之间需要彼此通信,那么新标签页就不能运行在独立的进程中。在Chrome中,将新创建的标签页的opener属性设置为null,即表示在单独的进程中运行新标签页,如下所示。

    var wroxWin = window.open("http://www.wrox.com/","wroxWindow",
                              "height=400,width=400,top=10,left=10,resizable=yes");
    
    wroxWin.opener = null;
    

    opener属性设置为null就是告诉浏览器新创建的标签页不需要与打开它的标签页通信,因此可以在独立的进程中运行。标签页之间的联系一旦切断,将没有办法恢复。

  1. 安全限制
  2. 弹出窗口屏蔽程序
  • 如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么window.open()很可能会返回null。此时,只要检测这个返回的值就可以确定弹出窗口是否被屏蔽了,如下面的例子所示。

    var wroxWin = window.open("http://www.wrox.com", "_blank");
    if (wroxWin == null){
        alert("The popup was blocked!");
    }
    
  • 如果是浏览器扩展或其他程序阻止的弹出窗口,那么window.open()通常会抛出一个错误。因此,要想准确地检测出弹出窗口是否被屏蔽,必须在检测返回值的同时,将对window.open()的调用封装在一个try-catch块中,如下所示。

    var blocked = false;
    
    try {
        var wroxWin = window.open("http://www.wrox.com", "_blank");
        if (wroxWin == null){
            blocked = true;
        }
    } catch (ex){
        blocked = true;
    }
    
    if (blocked){
        alert("The popup was blocked!");
    }
    

    在任何情况下,以上代码都可以检测出调用window.open()打开的弹出窗口是不是被屏蔽了。但要注意的是,检测弹出窗口是否被屏蔽只是一方面,它并不会阻止浏览器显示与被屏蔽的弹出窗口有关的消息。

间歇调用和超时调用

JavaScript是单线程语言,但它允许通过设置超时值间歇时间值来调度代码在特定的时刻执行。前者是在指定的时间过后执行代码,而后者则是每隔指定的时间就执行一次代码。

  • 超时调用

    • 超时调用需要使用window对象的setTimeout()方法

    • 接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前需要等待多少毫秒)。

      • 其中,第一个参数可以是一个包含JavaScript代码的字符串(就和在eval()函数中使用的字符串一样),也可以是一个函数。

      • 例如,下面对setTimeout()的两次调用都会在一秒钟后显示一个警告框。

        //不建议传递字符串!
        setTimeout("alert('Hello world!') ", 1000);
        
        //推荐的调用方式
        setTimeout(function() { 
            alert("Hello world!"); 
        }, 1000);
        
      • 第二个参数是一个表示等待多长时间的毫秒数,但经过该时间后指定的代码不一定会执行。

      • setTimeout()的第二个参数告诉JavaScript再过多长时间把当前任务添加到队列中。如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么它就要等前面的代码执行完了以后再执行。

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

      • 要取消尚未执行的超时调用计划,可以调用clearTimeout()方法并将相应的超时调用ID作为参数传递给它

      • //设置超时调用
        var timeoutId = setTimeout(function() {
            alert("Hello world!");
        }, 1000);
        
        //注意:把它取消
        clearTimeout(timeoutId);
        
      • 只要是在指定的时间尚未过去之前调用clearTimeout(),就可以完全取消超时调用

  • 间歇调用

    • 按照指定的时间间隔重复执行代码,直至间歇调用被取消或者页面被卸载

    • 设置间歇调用的方法是setInterval()

    • 接受的参数与setTimeout()相同:要执行的代码(字符串或函数)和每次执行之前需要等待的毫秒数。

    • //不建议传递字符串!
      setInterval ("alert('Hello world!') ", 10000);
      
      //推荐的调用方式
      setInterval (function() { 
          alert("Hello world!"); 
      }, 10000);
      
    • 调用setInterval()方法同样也会返回一个间歇调用ID,该ID可用于在将来某个时刻取消间歇调用

    • 要取消尚未执行的间歇调用,可以使用clearInterval()方法并传入相应的间歇调用ID

    • 取消间歇调用的重要性要远远高于取消超时调用,因为在不加干涉的情况下,间歇调用将会一直执行到页面卸载

    • var num = 0;
      var max = 10;
      var intervalId = null;
      
      function incrementNumber() {
          num++;
      
          //如果执行次数达到了max设定的值,则取消后续尚未执行的调用
          if (num == max) {
              clearInterval(intervalId);
              alert("Done");
          }
      }
      
      intervalId = setInterval(incrementNumber, 500);
      

      在这个例子中,变量num每半秒钟递增一次,当递增到最大值时就会取消先前设定的间歇调用。这个模式也可以使用超时调用来实现,如下所示。

      var num = 0;
      var max = 10;
      
      function incrementNumber() {
          num++;
      
          //如果执行次数未达到max设定的值,则设置另一次超时调用
          if (num < max) {
              setTimeout(incrementNumber, 500);
          } else {
              alert("Done");
          }
      }
      
      setTimeout(incrementNumber, 500);
      
  • 一般认为,使用超时调用来模拟间歇调用的是一种最佳模式。在开发环境下,很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动。而像前面示例中那样使用超时调用,则完全可以避免这一点。所以,最好不要使用间歇调用。

系统对话框

浏览器通过alert()confirm()prompt()方法可以调用系统对话框向用户显示消息。

通过这几个方法打开的对话框都是同步和模态的。也就是说,显示这些对话框的时候代码会停止执行,而关掉这些对话框后代码又会恢复执行。

  • alert()方法

    • 接受一个字符串并将其显示给用户
    • 调用alert()方法的结果就是向用户显示一个系统对话框,其中包含指定的文本和一个OK(“确定”)按钮
    • 通常使用alert()生成的“警告”对话框向用户显示一些他们无法控制的消息,例如错误消息。而用户只能在看完消息后关闭对话框
    • image-20200829182730491
  • confirm()方法

    • “确认”对话框除了显示OK按钮外,还会显示一个Cancel(“取消”)按钮,两个按钮可以让用户决定是否执行给定的操作

    • image-20200829182810071

    • 为了确定用户是单击了OK还是Cancel,可以检查confirm()方法返回的布尔值:true表示单击了OK,false表示单击了Cancel或单击了右上角的X按钮

      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()方法

    • 这是一个“提示”框,用于提示用户输入一些文本。提示框中除了显示OK和Cancel按钮之外,还会显示一个文本输入域,以供用户在其中输入内容。

    • image-20200829183138494

    • prompt()方法接受两个参数:要显示给用户的文本提示和文本输入域的默认值(可以是一个空字符串)。

      var result = prompt("What is your name? ", "");
      if (result !== null) {
          alert("Welcome, " + result);
      }
      
    • 如果用户单击了OK按钮,则prompt()返回文本输入域的值;如果用户单击了Cancel或没有单击OK而是通过其他方式关闭了对话框,则该方法返回null

  • 除了上述三种对话框之外,Google Chrome浏览器还引入了一种新特性。如果当前脚本在执行过程中会打开两个或多个对话框,那么从第二个对话框开始,每个对话框中都会显示一个复选框,以便用户阻止后续的对话框显示,除非用户刷新页面

  • 两个可以通过JavaScript打开的对话框,即“查找”和“打印”

    • 这两个对话框都是异步显示的,能够将控制权立即交还给脚本。这两个对话框与用户通过浏览器菜单的“查找”和“打印”命令打开的对话框相同。

    • avaScript中则可以像下面这样通过window对象的find()print()方法打开它们

      //显示“打印”对话框
      window.print();
      
      //显示“查找”对话框
      window.find();
      

location对象

提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。事实上,location对象是很特别的一个对象,因为它既是window对象的属性,也是document对象的属性

换句话说,window.locationdocument.location引用的是同一个对象

location对象的用处不只表现在它保存着当前文档的信息,还表现在它将URL解析为独立的片段,让开发人员可以通过不同的属性访问这些片段

下表列出了location对象的所有属性(注:省略了每个属性前面的location前缀)。

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

虽然通过上面的属性可以访问到location对象的大多数信息,但其中访问URL包含的查询字符串的属性并不方便。尽管location.search返回从问号到URL末尾的所有内容,但却没有办法逐个访问其中的每个查询字符串参数。为此,可以像下面这样创建一个函数,用以解析查询字符串,然后返回包含所有参数的一个对象

function getQueryStringArgs() {
  //取得查询字符串并去掉开头的问号
  var qs = location.search.length > 0 ? location.search.substring(1) : '',
    //保存数据的对象
    args = {},
    //取得每一项
    items = qs.length ? qs.split('&') : [],
    item = null,
    name = null,
    value = null,
    //在for循环中使用
    i = 0,
    len = items.length;

  //逐个将每一项添加到args对象中
  for (i = 0; i < len; i++) {
    item = items[i].split('=');
    name = decodeURIComponent(item[0]);
    value = decodeURIComponent(item[1]);

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

  return args;
}

位置操作

使用location对象可以通过很多方式来改变浏览器的位置

  • assign()

    • 为其传递一个URL

    • location.assign("http://www.wrox.com");
      
  • 如果是将location.hrefwindow.location设置为一个URL值,也会以该值调用assign()方法。例如,下列两行代码与显式调用assign()方法的效果完全一样。

    window.location = "http://www.wrox.com";
    location.href = "http://www.wrox.com";
    

    在这些改变浏览器位置的方法中,最常用的是设置location.href属性。

  • 修改location对象的其他属性也可以改变当前加载的页面

    //假设初始URL为http://www.wrox.com/WileyCDA/
    
    //将URL修改为"http://www.wrox.com/WileyCDA/#section1"
    location.hash = "#section1";
    
    //将URL修改为"http://www.wrox.com/WileyCDA/?q=javascript"
    location.search = "?q=javascript";
    
    //将URL修改为"http://www.yahoo.com/WileyCDA/"
    location.hostname = "www.yahoo.com";
    
    //将URL修改为"http://www.yahoo.com/mydir/"
    location.pathname = "mydir";
    
    //将URL修改为"http://www.yahoo.com:8080/WileyCDA/"
    location.port = 8080;
    

    每次修改location的属性(hash除外),页面都会以新URL重新加载

  • replace()

    • 当通过上述任何一种方式修改URL之后,浏览器的历史记录中就会生成一条新记录,因此用户通过单击“后退”按钮都会导航到前一个页面

    • 禁用这种行为,可以使用replace()方法

    • 这个方法只接受一个参数,即要导航到的URL;结果虽然会导致浏览器位置改变,但不会在历史记录中生成新记录

    • location.replace("http://www.wrox.com/")
      
  • reload()

    • 重新加载当前显示的页面

    • 调用reload()时不传递任何参数,页面就会以最有效的方式重新加载,从浏览器缓存中重新加载

    • 如果要强制从服务器重新加载,则需要像下面这样为该方法传递参数true

    • location.reload();        //重新加载(有可能从缓存中加载)
      location.reload(true);    //重新加载(从服务器重新加载)
      
    • 位于reload()调用之后的代码可能会也可能不会执行,这要取决于网络延迟或系统资源等因素。为此,最好将reload()放在代码的最后一行。

navigator对象

每个浏览器中的navigator对象也都有一套自己的属性

检测插件

检测浏览器中是否安装了特定的插件是一种最常见的检测例程。对于非IE浏览器,可以使用plugins数组来达到这个目的。该数组中的每一项都包含下列属性。

  • name:插件的名字。
  • description:插件的描述。
  • filename:插件的文件名。
  • length:插件所处理的MIME类型数量。

一般来说,name属性中会包含检测插件必需的所有信息,但有时候也不完全如此。在检测插件时,需要像下面这样循环迭代每个插件并将插件的name与给定的名字进行比较。

//检测插件(在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"));

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

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

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

//检测QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));

在这个例子中,函数hasIEPlugin()只接收一个COM标识符作为参数。在函数内部,首先会尝试创建一个COM对象的实例。之所以要在try-catch语句中进行实例化,是因为创建未知COM对象会导致抛出错误。这样,如果实例化成功,则函数返回true;否则,如果抛出了错误,则执行catch块,结果就会返回false。例子最后检测IE中是否安装了Flash和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());

上面代码中定义了两个函数:hasFlash()hasQuickTime()。每个函数都是先尝试使用不针对IE的插件检测方法。如果返回了false(在IE中会这样),那么再使用针对IE的插件检测方法。如果IE的插件检测方法再返回false,则整个方法也将返回false。只要任何一次检测返回true,整个方法都会返回true

注册处理程序

随着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()方法

    • 接收三个参数:要处理的协议(例如,mailtoftp)、处理该协议的页面的URL和应用程序的名称

    • 例如,要想将一个应用程序注册为默认的邮件客户端,可以使用如下代码。

      navigator.registerProtocolHandler("mailto",
          "http://www.somemailclient.com?cmd=%s", "Some Mail Client");
      

      这个例子注册了一个mailto协议的处理程序,该程序指向一个基于Web的电子邮件客户端。同样,第二个参数仍然是处理相应请求的URL,而%s则表示原始的请求。

screen对象

screen对象基本上只用来表明客户端的能力,其中包括浏览器窗口外部的显示器的信息,如像素宽度和高度等。每个浏览器中的screen对象都包含着各不相同的属性

属  性说  明IEFirefoxSafari/ ChromeOpera
availHeight屏幕的像素高度减系统部件高度之后的值(只读)
availLeft未被系统部件占用的最左侧的像素值(只读)
availTop未被系统部件占用的最上方的像素值(只读)
availWidth屏幕的像素宽度减系统部件宽度之后的值(只读)
bufferDepth读、写用于呈现屏外位图的位数
colorDepth用于表现颜色的位数;多数系统都是32(只读)
deviceXDPI屏幕实际的水平DPI(只读)
deviceYDPI屏幕实际的垂直DPI(只读)
fontSmooth-ingEnabled表示是否启用了字体平滑(只读)
height屏幕的像素高度
left当前屏幕距左边的像素距离
logicalXDPI屏幕逻辑的水平DPI(只读)
logicalYDPI屏幕逻辑的垂直DPI(只读)
pixelDepth屏幕的位深(只读)
top当前屏幕距上边的像素距离
updateInterval读、写以毫秒表示的屏幕刷新时间间隔
width屏幕的像素宽度

有时候也可能会用到其中的信息来调整浏览器窗口大小,使其占据屏幕的可用空间

window.resizeTo(screen.availWidth, screen.availHeight);

前面曾经提到过,许多浏览器都会禁用调整浏览器窗口大小的能力,因此上面这行代码不一定在所有环境下都有效

history对象

history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。因为historywindow对象的属性,因此每个浏览器窗口、每个标签页乃至每个框架,都有自己的history对象与特定的window对象关联

出于安全方面的考虑,开发人员无法得知用户浏览过的URL。不过,借由用户访问过的页面列表,同样可以在不知道实际URL的情况下实现后退和前进

  • 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.back();
        
        //前进一页
        history.forward();
        
  • length属性

    • 保存着历史记录的数量

    • 这个数量包括所有历史记录,即所有向后和向前的记录。对于加载到窗口、标签页或框架中的第一个页面而言,history.length等于0

    • 通过像下面这样测试该属性的值,可以确定用户是否一开始就打开了你的页面。

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

虽然history并不常用,但在创建自定义的“后退”和“前进”按钮,以及检测当前页面是不是用户历史记录中的第一个页面时,还是必须使用它

小结

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值