# 8. BOM

## window对象 <a href="#window-object" id="window-object"></a>

全局变量会成为 `window` 对象的属性，但是定全局变量与在 `window` 对象上直接定义属性的差别：全局变量不能通过 `delete` 操作符删除，而直接在 window 对象上的定义的属性可以。

```javascript
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
```

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

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

  但不同浏览器的坐标起点不同，无法在跨浏览器的条件下取得窗口左边和上边的精确坐标值。
* **窗口大小** 不同浏览器会有所不同。IE9+、Firefox、Safari、Opera 和 Chrome 提供以下4个属性：

  ```javascript
  window.outerWidth;
  window.outerHeight;
  window.innerWidth;
  window.innerHeight;
  // IE8
  document.documentElement.clientWidth;
  document.documentElement.clientHeight;
  // 通常先判断 window.outerWidth 是否可用
  ```

  使用 `resizeTo()` 和 `resizeBy()` 方法可以调整浏览器窗口的大小。这两个方法都接收两个参数，其中 `resizeTo()` 接收浏览器窗口的新宽度和新高度，而 `resizeBy()` 接收新窗口与原窗口的宽度和高度之差。有可能被浏览器禁用，同样不适用于框架，而只能对最外层的 `window` 对象使用。

  ```javascript
  //调整到 100×100
  window.resizeTo(100, 100);
  //调整到 200×150
  window.resizeBy(100, 50);
  //调整到 300×300
  window.resizeTo(300, 300);
  ```
* **导航和打开窗口**

  `window.open` 接收 4 个参数：要加载的 URL、窗口目标、一个特性字符串以及一个表 示新页面是否取代浏器历史记录中当前加载页面的布尔值。通常只须传递第一个参数，最后一个参数只在不打开新窗口的情况下使用。此外，第二个参数也可以是下列任何一个特殊的窗口名称： `_self` 、 `_parent` 、 `_top` 或 `_blank` 。第三个参数是一个逗号分隔的设置字符串，表示在新窗口中都显示哪些特性。下表列出了可以出现在这个字符串中的设置选项。

  ![](/files/-M2XYJU_o5OMgLJDZwqP)

  ```javascript
  // 等同于< a href="http://www.wrox.com" target="topFrame"></a>
  window.open("http://www.wrox.com/", "topFrame"); 
  var wroxWin = window.open("http://www.wrox.com/","wroxWindow",
  "height=400,width=400,top=10,left=10,resizable=yes");
  // 调整大小
  wroxWin.resizeTo(500,500);
  // 移动位置
  wroxWin.moveTo(100,100);
  // 关闭
  wroxWin.close();
  alert(wroxWin.closed); //true
  ```

  大多数浏览器都内置有弹出窗口屏蔽程序。浏览器内置的屏蔽程序阻止的弹出窗口，那

  么 `window.open()` 很可能会返回 `null`，浏览器扩展或其他程序阻止通常会抛出一个错误。

  ```javascript
  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!");
  }
  ```
* **setTimeout()和setInterval()** 异步方法，类似预约制排队取号。`setTimeout` 都是在全局作用域中执行的，因此函数中 `this` 的值在非严格模式下指向 `window` 对象，在严格模式下是 `undefined` 。

  ```javascript
  var timeoutId = setTimeout(function() {
    alert("Hello world!"); // 会返回一个数值 ID
  }, 1000); // 
  //注意：把它取消
  clearTimeout(timeoutId);

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

  function incrementNumber() {
    num++;
    // 如果执行次数未达到 max  设定的值，则设置另一次setTimeout
    if (num < max) {
      setTimeout(incrementNumber, 500);
    } else {
        alert("Done");
    }
  }
  setTimeout(incrementNumber, 500);
  ```

  一般认为，使用 `setTimeout()` 来模拟 `setInterval()` 是一种最佳模式。在开发环境下，很少使用真正的 `setInterval()`，原因是后一个 `setInterval()` 可能会在前一个 `setInterval()` 结束之前启动。而像前面示例中那样使用 `setTimeout()` ，则完全可以避免这一点。所以，最好不要使用 `setInterval()` 。
* **系统对话框** 浏览器通过 `alert()` 、 `confirm()` 和 `prompt()` 方法可以调用系统对话框向用户显示消息。通过这几个方法打开的对话框都是同步和模态的。

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

## location对象 <a href="#location-object" id="location-object"></a>

`location` 是最有用的`BOM` 对象之一，保存着当前文档的信息，将 `URL` 解析为独立的片段；既是 `window` 对象的属性，也是 `document` 对象的属性；换句话说，`window.location` 和 `document.location` 引用的是同一个对象。下表列出了它所有属性： ![](/files/-M2XYJUftGK-wo0wj17Y) ![location示例](/files/-M2XYJUhZddP3Oj26uej)

* **位置操作**

  ```javascript
  // 3种方法 立即打开新 URL 并在浏览器的历史记录中生成一条记录。
  location.assign("http://www.wrox.com");
  window.location = "http://www.wrox.com";
  location.href = "http://www.wrox.com";
  // 不会在历史记录中生成新记录。用户不能回到前一个页面
  location.replace("http://www.wrox.com/");
  // 重新加载 
  location.reload(); // 有可能从缓存中加载）
  location.reload(true); // 从服务器重新加载
  // 位于 reload() 调用之后的代码可能会也可能不会执行，这要取决于网络或系统资源等因素。最好将 reload() 放在代码的最后一行。
  ```

  修改 `location` 对象的其他属性也可以改变当前加载的页面，每次修改 `location` 的属性（ `hash` 除外），页面都会以新 URL 重新加载。

  ```javascript
  //将 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;
  ```

## navigator对象 <a href="#navigator-object" id="navigator-object"></a>

`navigator` 对象与其他 `BOM` 对象的情况一样，每个浏览器中的 `navigator` 对象也都有一套自己的属性。下表列出了存在于所有浏览器中的属性和方法，以及支持它们的浏览器版本。 ![](https://github.com/JaimeCheng/JavaScript-Notes/tree/7ef2f1827be873b72970e643622039ca4e7cf0fd/img/8-4.png) ![Chrome navigator示例](/files/-M2XYJUjSza3G3wBEX1i)

## screen对象 <a href="#screen-object" id="screen-object"></a>

`screen` 对象基本上只用来表明客户端的能力，其中包括浏览器窗口外部的显示器的信息，如像素宽度和高度等。每个浏览器(PC/Mobile)中的 `screen` 对象都包含着各不相同的属性，下表列出了所有属性及支持相应属性的浏览器。 ![](https://github.com/JaimeCheng/JavaScript-Notes/tree/7ef2f1827be873b72970e643622039ca4e7cf0fd/img/8-6.png)

## history对象 <a href="#history-object" id="history-object"></a>

`history` 对象保存着用户上网的历史记录，从窗口被打开的那一刻算起。

```javascript
//后退一页
history.go(-1);
//前进一页
history.go(1);
//前进两页
history.go(2);
//跳转到最近的 wrox.com 页面 如果历史记录中不包含该字符串，则什么也不做
history.go("wrox.com");
//后退一页
history.back();
//前进一页
history.forward();
if (history.length == 0){
  //这应该是用户打开窗口后的第一个页面
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jaimecheng.gitbook.io/javascript/content/chapter08.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
