《JavaScript高级程序设计(第3版)》第8章 BOM总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010011236/article/details/86436748

8.1、window 对象

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

8.1.1、全局作用域

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

定义全局变量和在 window 对象上定义属性的差别是:定义的全局变量不能使用 delete 操作符删除,而直接在 window 对象上定义的属性可以使用 delete 操作符进行删除。

var age = 29;
window.color = 'red';

console.log(delete window.age);   // false
console.log(delete window.color); // true

console.log(window.age);    // 29
console.log(window.color);  // undefined

使用 var 语句添加的 window 属性有一个名为 [[Configurable]] 的特性,这个特性的值被设置为 false,因此这样定义的属性不可以通过 delete 操作符删除。IE8及更早版本在遇到使用 delete 删除 window 属性的语句时,不管该属性最初是如何创建的,都会抛出错误,以示警告。IE9及更高版本不会抛出错误。

注意:尝试访问未声明的变量会抛出错误,但是通过查询 window 对象,可以知道某个可能未声明的变量是否存在。

// 这里会抛出错误,因为oldValue未定义
var newValue = oldValue;
// 这里不会抛出错误,因为这是一次属性查询
var newValue1 = window.oldValue;
console.log(newValue1);  // undefined

8.1.2、窗口关系及框架

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

<frameset rows="160,*">
  <frame src="test8.html" name="topFrame">
  <frameset cols="50%,50%">
    <frame src="test9.html" name="leftFrame">
    <frame src="test10.html" name="rightFrame">
  </frameset>
</frameset>

top 对象始终指向最高(最外)层的框架,也就是浏览器窗口。

                                                   图1

parent 对象始终指向当前框架的直接上层框架。在某些情况下,parent 有可能等于 top;但在没有框架的情况下,parent 一定等于 top (此时它们都等于 window)。

注意:除非最高层窗口是通过 window.open() 打开的,否则其 window 对象的 name 属性不会包含任何值。

与框架有关的最后一个对象是 self,它始终指向 window;实际上,self 和 window 对象可以互换使用。

8.1.3、窗口位置

screenLeft(screenX) :窗口相对于屏幕左边的位置;

screenTop(screenY) :窗口相对于屏幕上边的位置。

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

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

将窗口精确的移动到一个新位置的方法:(1)moveTo() ; (2)moveBy() 方法。

(1)moveTo():接收的是新位置的 x 和 y 坐标值。

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JavaScript高级程序设计 第8章 测试</title>
  <style>
    #container {
      text-align: center;
    }
  </style>
</head>
<body>
<div id="container">
  <button onclick="openWin()">Create new window</button>
  <button onclick="moveWinTo()">Move new window</button>
  <button onclick="moveWinBy()">Move the new window by 75 * 50px</button>
</div>
</body>
<script>
  var myWindow;

  function openWin() {
    myWindow = window.open("","", "width=250, height=250");
  }

  function moveWinTo() {
    myWindow.moveTo(150, 150);
    myWindow.focus();
  }

  function moveWinBy() {
    myWindow.moveBy(75, 50);
    myWindow.focus();
  }
</script>
</html>

8.1.4、窗口大小

在 IE9+、Safari、Firefox中,outerWidth 和 outerHeight 返回浏览器窗口本身的尺寸(无论是从最外层的 window 对象还是从某个框架访问)。

在 Opera 中,这两个属性的值表示页面视图容器的大小。而 innerWidth 和 innerHeight 则表示该容器中页面视图区的大小(减去边框宽度)。

在 Chrome 中,outerWidth、outerHeight 与 innerWidth、innerHeight 返回相同的值,即视口(viewport)大小而非浏览器窗口大小

注意:在 IE、Firefox、Safari、Opera 和 Chrome 中,document.documentElement.clientWidth 和 document.documentElement.clientHeight 中保存了页面视口信息。在 IE6 中,这些属性必须在标准模式下才有效;如果是混杂模式,就必须通过 document.body.clientWidth 和 document.body.clientHeight 取得相同信息。

注意:在 Chrome 中取得视口的大小的方法:

(1)outerWidth、outerHeight;

(2)innerWidth、innerHeight;

(3)document.documentElement.clientWidth、document.documentElement.clientHeight;

(4)document.body.clientWidth、document.body.clientHeight:取得的是页面中 body 的宽和高

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JvavScript高级程序设计 第8章 测试</title>
  <script>
    // 在chrome中测试
    // 1536,1536,1536
    alert('width = ' + window.outerWidth + ',' + window.innerWidth + ',' + document.documentElement.clientWidth);
  </script>
</head>
<body>
  <p>hello world</p>
</body>
<script>
  alert('width = ' + document.body.clientWidth);    // 1520
  alert('height = ' + document.body.clientHeight);  // 21
</script>
</html>

虽然最终无法确定浏览器窗口本身的大小,但却可以取得页面视口的大小。

var pageWidth = window.innerWidth;
var pageHeight = window.innerHeight;

if (typeof pageWidth != 'number') {
    // 检测页面是否属于标准模式
    if (document.compatMode == 'CSS1Compat') {
        pageWidth = document.documentElement.clientWidth;
        pageHeight = document.documentElement.clientHeight;
    } else {
        pageWidth = document.body.clientWidth;
        pageHeight = document.body.clientHeight;
    }
}

注意:对于移动设备,window.innerWidth 和 window.innerHeight 保存在可视口,也就是屏幕上可见页面区域的大小。在其他移动浏览器中,document.documentElement 度量的是布局视口,即渲染后页面的实际大小(与可见视口不同,可见视口只是整个页面中的一小部分)。

调整浏览器窗口大小的两个方法:(1)resizeTo();(2)resizeBy()。

(1)resizeTo():接收浏览器窗口的新宽度和高度;

(2)resizeBy():浏览器窗口增加的宽度和高度。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <style>
    #container {
      text-align: center;
    }
  </style>
</head>
<body>
<div id="container">
  <button onclick="openWin();">Create new window</button>
  <button onclick="resizeWinTo();">Resize to new window</button>
  <button onclick="resizeWinBy();">Resize by new window</button>
</div>
</body>
<script>
  var myWindow;

  function openWin() {
    myWindow = window.open("", "", "width=250, height=250");
  }

  function resizeWinTo() {
    myWindow.resizeTo(500, 500);
    myWindow.focus();
  }

  function resizeWinBy() {
    myWindow.resizeBy(200, 50); // 宽度增加200px,高度增加50px
    myWindow.focus();
  }
</script>
</html>

注意:这两个方法不使用于框架,而只能对最外层的 window 对象使用。

8.1.5、导航和打开窗口

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

window.open() 方法接收四个参数:

  • 第一个参数:要加载的 URL
  • 第二个参数:窗口目标(也可以是:_self:在当前窗口打开URL、_parent、_top、_blank)
  • 第三个参数:一个特性字符串
  • 第四个参数:一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值

通常只需传递第一个参数,最后一个参数只在不打开新窗口的情况下使用。

如果为 window.open() 传递第二个参数,而且该参数是已有窗口或框架的名称,那么就会在具有该窗口或框架中加载第一个参数指定的 URL。

// 等同于 <a href="http://www.wrox.com" target="topFrame"></a>
// 会在框架名为 'topFrame' 的框架中打开该链接
window.open('http://www.wrox.com', 'topFrame');

即如果有一个名叫 "topFrame" 的窗口或者框架,就会在该窗口或框架加载这个 URL;否则,就会创建一个新窗口并将其命名为 "topFrame" 。

1. 弹出窗口

如果给 window.open() 方法传递的第二个参数并不是一个已经存在的窗口或框架,那么该方法就会根据第三个参数位置上传入的字符串创建一个新窗口或新标签页(没有工具栏、地址栏、状态栏等)。如果没有传入第三个参数,那么就会打开一个带有全部默认设置(工具栏、地址栏、状态栏等)的新浏览器窗口(或者打开一个新标签页——根据浏览器设置)。

window.open() 方法的第三个参数是一个逗号分隔的设置字符串,表示在新窗口中都显示哪些特性。具体设置项如下表所示:

                                                                            图2

上图中有些设置对于 chrome、Firefox 无效。

// 其中 resizable 对 IE 有效果
window.open('http://www.wrox.com/', 'wroxWindow', "width=400,height=400,top=10,left=10,resizable=yes");

注意:window.open()  方法会返回一个指向新窗口的引用。

window.open() 方法返回对象的作用:有些浏览器在默认的情况下可能不允许我们针对主浏览器窗口调整大小或移动位置,但却允许我们针对通过 window.open() 创建的窗口调整大小或移动位置。

var wroxWin = window.open('http://www.wrox.com/', 'wroxWindow', 'width=400,height=400,top=10,=left=10');

// 调整大小
wroxWin.resizeTo(500, 500);

// 移动位置
wroxWin.moveTo(50, 50);

wroxWin.close(); // 关闭窗口

注意:弹出窗口关闭之后,窗口的引用仍然存在,但除了像下面这样检测 closed 属性之外,已经没有其他用处了。

wroxWin.close();
alert(wroxWin.closed);  // true

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

var wroxWin = window.open('http://www.wrox.com/', 'wroxWindow', 'width=400,height=400,top=10,=left=10');

alert(wroxWin.opener == window);  // true

当一个标签页打开另一个标签页时,如果两个 window 对象之间需要彼此通信,那么新标签页就不能运行在独立的进程中。在 chrome 中,将新创建的标签页的 opener 属性设置为 null,即表示在单独的进程的中运行新标签页。

var wroxWin = window.open('http://www.wrox.com/', 'wroxWindow', 'width=400,height=400,top=10,=left=10');

wroxWin.opener = null; // 在 chrome 中,表示在单独的进程中运行新标签页

2.弹出窗口屏蔽程序

如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么 window.open() 很可能会返回 null 。此时,只要检测这个返回的值就可以确定弹出窗口是否被屏蔽了。

var wroxWin = window.open('http://www.wrox.com/', 'wroxWindow', 'width=400,height=400,top=10,=left=10');

if (wroxWin == null) {
    alert('The popup was blocked!');
}

8.1.6、间歇调用和超时调用

(1)超时调用:setTimeout() 方法

setTimeout() 方法接收两个参数:第一个参数为包含js代码的字符串或函数,第二个参数表示等待多少毫秒数。

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

该方法的返回值:一个数值 ID,表示超时调用。要取消尚未执行的超时调用计划,可以调用 clearTimeout() 方法并将相应的超时调用 ID 作为参数传递给它。

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

注意:只要在指定的实际尚未过去之前调用 clearTimeout(),就可以完全取消超时调用。超时调用的代码都是在全局作用域中执行的,因此函数中 this 的值在非严格模式下指向 window 对象,在严格模式下是 undefined。

(2)间歇调用:setInterval() 方法

setInterval() 方法:按照指定的时间间隔重复执行代码,直至该调用被取消或者页面被卸载。

其接收的两个参数和 setTimeout() 方法是一样的,只不过第二个参数表示代码重复执行的时间间隔。

该方法会返回一个间歇调用 ID,该 ID 用于在将来某个时刻取消间歇调用。可以通过 clearInterval() 方法并传入相应的间歇调用 ID 来取消间歇调用。

注意使用超时调用来模拟间歇调用是一种最佳模式。在开发环境下,很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动

8.1.7、系统对话框

系统对话框:alert()、confirm()、prompt()。

这三个方法都是同步和模态的:显示这些对话框的时候代码会停止执行,而关掉这些对话框后代码又会恢复执行。

alert('hello world');    // 如图3所示
confirm('hello world');  // 如图4所示
prompt('hello world');   // 如图5所示

                                        图3

                                        图4

                                        图5

可以检查 confirm() 方法返回的布尔值:true 表示单击了确认,false 表示单击了取消。

if (confirm('hello world')){
    alert("I'm so glad you're sure!");
} else {
    alert("I'm sorry to hear you're not sure.");
}

prompt() 方法接受两个参数:要显示给用户的文本提示文本输入域的默认值(可以是一个空字符串)。如果用户单击了确认,则返回文本输入域中的值;如果用户单击了取消或者没有单击确认而是通过其他方式关闭了对话框,则返回 null

var result = prompt("What's your name?", "");
if (result != null) {
    console.log('Welcome, ' + result);
}

8.2、location 对象

location 对象既是 window 对象的属性,也是 document 对象的属性;即 window.loaction 和 document.loaction 引用的是同一个对象。

location 对象可以将 URL 解析为独立的片段,可以通过不同的属性来访问这些独立的片段。该对象的属性如图6所示。

                                                                       图6

8.2.1、查询字符串

location.search 返回从问好到 URL 末尾的所有内容,但却没有办法逐个访问其中的每个查询字符串参数。可以通过如下方法解决该问题:

function getQueryStringArgs() {
    // 取得查询字符串并去掉开头的问好
    var qs = (location.search.length > 0 ? location.search.substring(1) : "");

    // 保存数据的对象
    args = {};

    // 取得每一项
    var items = qs.length ? qs.split('&') : [];
    var item = null,
        name = null,
        value = null;

    // 在for循环中使用
    var 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;
}

//假设查询的字符串为:http://localhost:63342/CodeTest/test2.html?_ijt=7f55sogskrtlabp769vkgjqg5q
var args = getQueryStringArgs();

console.log(args['_ijt']);

8.2.2、位置操作

改变浏览器的位置:(1)location.assign() 方法;(2)location.href;(3)window.location。而为(2)和(3)设置一个URL值实际上会调用 location.assign() 方法。

location.assign('http://www.wrox.com');
location.href = 'http://www.wrox.com';
window.location = 'http://www.wrox.com';

上述代码会立即打开新的URL并在浏览器的历史记录中生成一条记录。

8.3、navigator 对象

注意:每个浏览器中的 navigator 对象都有一套自己的属性。

浏览器内置插件检测代码如下所示:

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

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

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

8.5、history 对象

history对象的方法:go();back();forward()。

history.go():在历史记录中任意跳转,正数表示前进,负数表示后退。

history.back():后退

history.forward():前进

参考文献

[1]《JavaScript高级程序设计(第3版)》

猜你喜欢

转载自blog.csdn.net/u010011236/article/details/86436748