JavaScript权威指南--window对象

知识要点

window对象及其客户端javascript所扮演的核心角色:它是客户端javascript程序的全局对象。本章介绍window对象的属性和方法,这些属性定义了不一样的API,可是只有一部分实际上和浏览器窗口相关。window对象是以窗口命名的javascript

1.计时器

setTimeout()和setIterval()能够用来注册在指定的时间以后单次或重复调用的函数。由于它们都是客户端javascript中的重要全局函数,因此定义为window对象方法,但做为通用函数,其实并不会对窗口作什么事情。html

window对象的setTimeout()方法用来实现一个函数在指定的毫秒后运行。setTimeout返回一个值,这个值能够传给clearTimeout()用于取消这个函数的执行。html5

/**定时器应用函数
 * 安排函数f()在将来的调用模式
 * 在等待了若干时间后调用f()
 * 若是设置了interval并无设置end参数,则f()的调用不会中止
 * 只有制定了f(),才会从start=0时刻开始
 * 注意,调用invoke()不会阻塞,会当即返回
 * */
function invoke(f, start, interval, end) {
    if (!start) start = 0;//默认设置为0
    if(arguments.length <=2)//单次调用模式
    setTimeout(f,start);//start秒后调用f
    else{      //屡次调用模式
        setTimeout(repeat,start);//若干秒后调用repeat()
        function repeat(){
            var h = setInterval(f,interval);//循环调用f()
            //在end结束后调用,嵌套是end已经定义了
            if(end) setTimeout(function(){clearInterval(h);},end);
        }
    }
}

谈谈setTimeout()和setInterval()问题java

因为历史缘由,setTimeout()和setInterval()第一个参数能够做为字符串传入。若是这么作,那这个字符串会在指定的超时时间或间隔以后求值(至关于执行eval()).除了前两个参数以外,HTML5规范还容许setTimeout()和setInterval()传入额外的参数,而且在调用函数的时候把这些参数传递过去。然而,若是须要支持IE的话,就不要应用此特性了。web

若是以0毫秒时间调用setTimeout,那么指定的函数不会马上执行。相反会把它放到队里中,等到前面处于等待状态的事件处理程序彻底完成以后,再马上调用它。正则表达式

补充:chrome

function parent(){   
    function child(){   
        setTimeout(child2(),1000);   
        setTimeout(parent2(),1000);   
        alert("use child1")   
        }   
    function child2(){   
        alert("use child2")   
        }   
    child();   
    }   
parent();//调用parent
function parent2(){   
    alert("I’m your mather")   
    } 

输出:直接按顺序输出:2-1-l`m。给第一个参数添加双引号成为字符串便可。小程序

function parent(){   
    function child(){   
        setTimeout("child2()",1000);   
        setTimeout("parent2()",1000);   
        console.log("use child1")   
    }   
    function child2(){   
        console.log("use child2")   
    }   
    child();   
}   
parent();//调用parent
function parent2(){   
    console.log("I’m your mather")   
}   

输出结果:segmentfault

这说明setTimeout只能访问全局对象的属性和方法,而不能访问私有做用域内的属性和方法。其实setTimeout是个window对象的一个方法,f是做为window对象的一个方法调用的,其效果就像一个<script>标签里面的代码同样只能访问,对于函数里面的变量和方法是没法访问的。这就是为何建议使用函数代替字符串的一个缘由。另外,传递字符串也有可能致使性能损失。数组

2.浏览器的定位和导航

window对象的location属性引用的是Location对象,它表示该窗口中当前显示的文档的URL,并定义了方法使窗口载入新的文档。

Document对象的location属性也引用到Location对象:

window.location === document.location; //=>true 老是返回true

Document对象也有一个URL属性,是文档首次载人后保存该文档的URL静态字符串。若是定位到文档中的片断标识符(如#table-of-contens),Location对象会作相应的更新,而document.url属性却不会改变。

2.1.解析url

window对象的location属性引用是Location对象,表示该窗口当前显示的的文档的URL。Location对象的href属性是一个字符串,包含URL的完整文本。Location对象的toString()方法返回href属性的值,所以会在隐式调用toString()状况下,使用location代替location.href。

var d = location.href;
var c = location.toString();
console.log(d === c)

这个对象的其它属性,protocol,host,hostname,port,pathname和search分别表示URL的各个部分。它们称为"URL分解",同时被Link对象(经过HTML文档中的a和<area>元素建立)支持,参阅本书的第四部分,Location和Link项获取详细信息。

Location对象的hash和seerch比较有趣。若是有的话,hash表示URL中的“片断标识符 #xx”部分,search返回问号以后的URL,这部分一般是某种类型的查询字符串。通常来讲这部份内容是用来参数化URL并在其中嵌入参数的。经常使用于运行在服务器上的脚本,但在启动JavaScript的页面中也可使用。

下面的例子展现了一个通用函数urlArgs()定义,能够用这个函数将参数从URL的search属性中提取出来。该例子用到了decodeURIComponent(),后者是在客户端Javascript定义的全局函数(参加本书第三章部分中的Global获取详细内容)。

/**
 *这个函数来解析来自URL的查询中串中的name=value参数
 * 它将name=value对象存储在一个对象的属性中,并返回该对象,这样使用它
 *
 * var args = urlArgs();//从URL中解析参数
 * var q = args.q ||"";//若是参数定义的话就使用它,不然使用默认值。
 * var n = args.n?parseInt(args.n):10
 **/
function urlArgs() {
    var args = {}; //空对象
    var query = location.search.substring(1); //?后的值
    var pairs = query.split("&");
    for (var i = 0; i < pairs.length; i++) { //对于每一个片断
        var pos = pairs[i].indexOf('=');
        if (pos == -1) continue; //若是没有找到的话,跳过
        var name = pairs[i].substring(0, pos); //提取name
        var value = pairs[i].substring(pos + 1); //提取value
        value = decodeURIComponent(value); //对value进行解码
        args[name] = value;
    }
    return args;
}

2.2.载入新的文档

Location对象的assign()方法可使窗口载入并显示你指定的url中的文档。replace()方法也相似,但它在载入新的文档以前会从浏览历史把当前文档删除。若是脚本无条件的载入一个新的文档,replace()方法是可能比assgin()方法更好的选择。不然,后退按钮会使用浏览器带回原始文档。而相同的脚本则会再次载入新文档。若是检测到用户浏览器不支持某些特性来显示功能齐全的版本,能够用location.replace()来载入静态的HTML版本:

 //若是浏览器不支持XMLHttpRequest对象
 //则将其重定向到一个不须要Ajax的静态页面
if (!XMLHttpRequest) location.replace("staticpage.html");

注意,在这个例子中传入replace()的是一个相对URL。相对URL是相对于当前页面所在的目录来解析的,就像将它们用于一个超连接中。

除了assign()和replace()方法,Location对象还定义了reload()方法,后者可让浏览器从新载入当前文档。

使浏览器跳转到新页面的一种更传统的方法是直接赋值给location

location = "https://segmentfault.com/";

也可用相对URL,它会对其进行解析:

location = "page.html";

纯粹的片断标识符也是url的一种类型,它不会让浏览器载入新文档,但只会使它滚动到文档的某个位置。#top标识符是一个特殊例子:若是文档没有元素额ID是"top",它会让浏览器跳转到文档开始处。

location = "#top";

Location对象的URL分解属性是可写的,对它们从新赋值会改变URL的位置,而且致使浏览器载入一个新的文档(若是改变的是hash属性,则在当前文档中进行跳转):

location.search = "?page=" + (pagename+1);//载入新的页面

3.浏览历史

window对象的history属性引用的是该窗口的History对象。History对象是用来把窗口的浏览历史用文档和文档状态列表的形式表示。History对象的length属性表示浏览历史列表中的元素数量,处于安全考虑,脚本不能访问已经保存的URL(若是容许那任意脚本均可以窥探浏览历史)。

history对象的back()和forward()方法与浏览器的“后退”和“前进”按钮同样。第三个方法go()接受一个参数,能够在历史列表向前(正参数)向后(幅参数)跳过任意个页面。

history.go(-2); //向后两个历史记录,至关于后退按钮两次

若是窗口包含多个子窗口(好比iframe见14.8.2节),子窗口的浏览历史会按时间顺序穿插在主窗口的历史中。这意味着在主窗口调用history.back()可能会致使其中一个子窗口往回跳到前一个显示文档,但主窗口保留当前状态不变。

现代的web应用能够不经过载入新的文档而动态的改变自身内容(1五、18章)。这么作可能但愿用户能用“后退”和“前进”按钮在这些动态建立应用状态之间跳转。html5将这些技术标准化(22章2节)。

HTML5以前的历史管理是个更复杂的难题。应用程序必需要在窗口浏览历史中建立一个新的条目来管理自身的历史记录。。。。。。

在实际的工做中,那些须要之前的HTML5历史管理的项目中,开发者会使用一些现成 解决方法,不少框架都实现了这些功能。例如jQuery的history插件。也有一些单独的管理历史记录的类库。RSH(Really Simple History)是其中一个比较流行的示例。(22章2节会有关于html5的历史管理)

4.浏览器和屏幕信息

本节介绍window对象的navigator和screen属性,它们分别引用的是Navigator和Screen对象,这些对象信息容许脚本根据环境定制的行为。

4.1.Navigator对象

window对象的navigator属性引用的是包含浏览器厂商和版本信息的Navigator对象。

这样命名是为了记念Netscape以后Navigator浏览器。

过去会用其来肯定脚本是在哪一种浏览器运行,如今浏览器种类繁多,也有一种更好的功能测试方法(13.4.3节)。可是Navigation仍是有价值的,在这种状况下有用:当须要解决存在于某个特定的浏览器的特定版本中的特殊的bug时。

可使用这些属性进行浏览器嗅探:

  • appName:web浏览器的全称,IE中,它显示“Microsoft Internet Exploer”.在firefox中,该属性就是“Netscape”,在其它浏览器中也是(为了兼容如今的浏览器嗅探码)。
  • appVersion:此属性一般以数字开始,并跟随浏览器开发商和版本信息等详细字符串。字符串的前边一般是4.0或者5.0,表示它是第4仍是第5代兼容的浏览器。appVersion没有标准格式。全部没有办法判断浏览器的类型
  • userAgent:浏览器在它的User-Agent HTTP头部发送的字符串。这个属性一般包含全部appVersion信息,而且经常包含其它细节。和appVersion同样,它也没有标准格式。因为这个属性包含绝大部分信息,所以,浏览器嗅探代码一般使用它。
  • platform:在其上运行的浏览器的操做系统(多是硬件的字符串)。
navigator.appName
//不是Navigator.appName,属性是引用Navigator对象

Navigator属性的复杂性正说明了浏览器嗅探对于处理客户端兼容性问题是没有太大帮助的。appName(都设为Netscape)和appVersion(有起始数字)没太大意义,因此使用更复杂的userAgent。

下面的例子展现了使用正则表达式(来自jQuery)从navigator.userAgent抽取浏览器的版本和名称方法代码。

 /* 使用naVigator.userAgent来进行浏览器嗅探  */
 //为客户端嗅探定义browser.name和browser.version,这里使用了jQuery1.41的代码
 //name和number都是字符串,对浏览器的输出结果不同,检测的结果以下
 //'webkit':safari或chrome,版本号是WebKit的版本号
 //'opera' Opear 版本号就是软件的把嫩好
 //"mozilla" Firefox或者基于gecko内核的浏览器,版本号是Gecko的版本
 //msie     IE+版本号
var browser = (function() {
            var s = navigator.userAgent.toLowerCase();
            var match = /(webkit)[ \/]([\w.]+)/.exec(s) ||
                /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(s) ||
                /(msie)([\w.]+)/.exec(s) ||
                !/compatible/.test(s) && /(mozilla)( ? : .* ? rv : ([\w.] + )) ? /.exec(s)||[];
        return{name:match[1]||"",version:match[2]||"0"};
}());

除了浏览器厂商和版本信息的属性以外,Navigator对象还包含一些杂项属性和方法。如下是一些标准化的属性以及普遍应用但未标准的属性:

  • OnLine:navigator.onLine是表示浏览器是否链接到网络。应用:判断离线的话就保存状态到本地(20章)
  • geolocation:navigator.geolocation对象拥有肯定用户地址位置信息的接口,参加22.1章节细节
  • javaEnabled():navigator.javaEnabled是一个非标准的方法,当浏览器能运行java小程序时返回true
  • cookieEnabled():navigator.cookieEnabled也是一个非标准方法,若是浏览器能够永久保存cookie时,返回true,而cookie配置“视具体状况而定”时,可能会返回不正确的值。

4.2.Screen对象。

window对象的screen属性引用的是Screen对象。它提供有关窗口的大小和可用的颜色数量的信息属性width和heigth指定的是以像素为单位的窗口大小,属性availWidth和availHeiht指是实际可用的显示大小,它们排除了像桌面任务栏这样的特性所占用的空间。属性colorDepth指定的是显示的BPP(bits-per-pixel)值,典型的值有16,24,32

window.screen属性和它引用的screen对象都是非标准但普遍实现的。能够用Screen对象来肯定web应用是否运行在一个小的屏幕设备上,若是屏幕有限,可能要选用更小的字体和图片等。

5.对话框

window对象提供了3个方法向用户显示简单的对话框,alert()向用户显示一条信息并等待用户关闭对话框,confirm()要求用户单击肯定或取消,返回一个布尔值,prompt()一样也显示一条消息,等待用户输入字符串,并返回那个字符串。下面的代码全用了这三种方法:

do {
    var name = prompt("你的名字");
    var correct = confirm("你输入了" + name + "\n" + "oK确认,chancel取消");
} while (!correct)
 alert("hello " + name);

尽管alert(),confirm()和prompt()都容易使用,可是良好的设计仍是须要有节制的使用它们。现在,惟一常见的就是使用它们调试,查看变量输出的结果是什么。

注意,这些对话框中显示的文本是纯文本,而不是HTML格式的文本,只能使用空格,换行符和各类标点符号来格式化这些对话框。

confirm()和prompt()都会产生阻塞,也就是说,在用户关掉它们所显示的对话框以前,它们不返回,代码会中止运行或载入,直到用户响应为止。在大多数浏览器里,alert()也会产生阻塞,并等待用户关闭对话框,但不老是这样,完整的的细节请参考第四部分的Window.alert()/Window.confirm()、和window.prompt()方法。

除了window的alert()、confirm()和prompt()方法,还有更复杂的方法showModalDialog(),显示一个包含HTML格式的模态对话框(显示出来就不能够点选位于其下面的对话框),能够给它传入参数,以及从对话框里返回值。第一个参数用以指定提供对话框HTML内容的URL,第二个参数是一个任意值(数组和对象都可),这个值在对话框里的脚本中能够经过window.dailogArguments属性的值访问。第三个参数是一个非标准的列表,包含以分号隔开的name=value对,若是提供了这个参数,能够配置对话框的尺寸和其余属性,用dialogwidth和dialogheight来设置对话框窗口的大小。用resizable=yes来容许用户改变窗口大小。

这个方法直到窗口关闭以前不会反悔。当窗口关闭后,window.returnValue属性的值就是此方法的返回值。对话框的HTML内容每每必须包含用来设置returnValue的“确认”按钮,若是须要则调用window.close(14.8.1节)。

下面的例子是一个适用于showModalDialog()的html文件,代码顶部注释包含调用showModalDialog()的样例。对话框里显示的大量文本都来自showModalDialog()第二个参数,而不是写死在html中。

。。。。。。

6.错误处理

window对象的onerror属性是一个事件处理程序,当未捕获的异常传播到调用栈上时就会调用它,并把错误消息输出到浏览器的javascript控制台上若是给这个属性赋值一个函数,那么只要这个窗口中发生了javascript错误,就会调用该函数,即它成为了窗口的错误处理程序。

因为历史缘由,window对象的onerror事件处理函数的调用经过三个字符串参数,而不是经过传递一个事件对象。(其它客户端对象的onerror处理程序所须要的错误条件是不同的,可是它们都是正常的事件处理程序,向这个函数只需传入一个事件对象。)window.onerror的第一个参数是描述错误的一条消息。第二个参数是一个字符串,它存放引起错误的javascript代码所在文档的 url.第三个参数是引起错误的行数。

除了这三个参数外,onerror处理程序的返回值也很重要。若是onerror处理程序返回false,它通知浏览器事件处理程序已经处理了错误,不须要其余操做。换句话说,浏览器不该该显示它本身的错误消息。遗憾的是,因为历史缘由,Firefox里的错误程序必须返回true表示它已经处理了错误

onerror处理程序是很早期的javascript产物,那时候语言核心不包含try/catch异常处理语句。如今的代码已经不多使用它。可是在开发阶段,你可能须要定义一个错误处理程序,当错误发生时,来显式的通知你。

//在一个对话框中弹出错误消息,但不超过3次
window.onerror = function(msg, url, line) {
    if(onerror.num++ < onerror.max){
        alert("出错了:\n" + msg + "\n 地址:" + url + "\n行号:" + line);
        return true; //屏蔽系统事件
    }
}
onerror.max = 3;
onerror.num = 0;

示例:

<html>
<head>
<script type="text/javascript">
onerror=handleErr
var txt=""

function handleErr(msg,url,l)
{
txt="本页中存在错误。\n\n"
txt+="错误:" + msg + "\n"
txt+="URL: " + url + "\n"
txt+="行:" + l + "\n\n"
txt+="点击“肯定”继续。\n\n"
alert(txt)
return true
}

function message()
{
ablert("Welcome guest!")
}
</script>
</head>

<body>
<input type="button" value="查看消息" onclick="message()" />
</body>

</html>

7.做为window对象属性的文档元素

若是在HTML文档中使用id属性来为元素命名,而且若是window对象没有此名字的属性,window对象会赋予一个属性,它的名字是id属性的值,而他们的值指向表示文档元素的HTMLElement对象。

//文档中存在id="doc"的HTML元素
window.doc

在客户端javascript中,window对象是以全局对象的形式存在于做用域链的最上层,这就意味着在html文档中使用的id属性会成为被脚本访问的全局变量。若是一个文档包含<button id="okay"></button>元素,能够经过全局变量okay引用此元素。

可是:有一个很重要的警告!若是window对象已经具备此名字的属性,这就不会发生。好比id是history,location或navigator的元素,就不会以全局变量的形式出现,由于这些id已经被占用了。一样,若是html文档包含一个id为“x”的元素,而且还在代码中声明并赋值给全局变量x,那么显式声明的变量会隐藏隐式的元素变量。若是脚本中的变量声明出如今命名元素以前,那这个变量的存在就会阻止元素获取它的window属性。而若是脚本中的变量声明出如今命名元素以后,那么变量的显式赋值就会覆盖该属性的隐式值。

15章2节中,你会学到经过document,getElementById()方法,用HTML的id属性来查找文档元素。见下面的例子:

var ui = ["input", "prompt", "heading"]; //数组中存放要查找的元素id
ui.forEach(function(id) { //用每一个id查找对于的元素
    ui[id] = document.getElementById(id); //将其存放在一个属性中
});

运行完这段代码以后,ui.input,ui.prompt和ui.heading会引用文档元素。脚本能够用全局变量input和heading来代替ui.input和ui.heading
但记得14.5节里window对象有个方法的名字是prompt(),所用脚本中不能用全局变量prompt代替ui.prompt。

元素的id做为全局变量的隐式应用是web浏览器演化过程当中遗留的怪癖。它主要是出于与已有web页面向后兼容性的考虑。但这里并不推荐这种作法---浏览器厂商能够在任什么时候候为window对象定义新属性,而这些新属性都会破坏使用了此属性名的隐式定义的代码。反之,用document.getElementById()来显式查找元素,若是给他一个更简单的名字,这种用法会更加简单:

var $ = function(id) {
    return document.getElementById(id);
};
ui.prompt = $("prompt")

假设ID并无被window对象使用的话,那么任何有id属性的html元素都会变成全局变量的值。如下HTML元素若是有name属性的话,也会这样表现:

<a> <applet> <area> <embed> <form> <frame> <frameset> <img> <object>

id元素在文档中必须是惟一的,两个元素不能有相同的id。可是这对name属性无效。若是上面的元素有多于一个相同的name属性(或者一个元素有name属性,而另一个元素有相同值的id属性),具备该名称的隐式全局变量会引用一个类数组对象,这个类数组对象的元素是全部命名的元素。

有name或id属性的<iframe>元素是个特殊的例子。为它们隐式建立的变量不会引用表示元素自身的Element对象,而是引用表示<iframe>元素建立的嵌套的window对象。本文14.8.2节会讨论到它。

8.多窗口和窗体

一个web页面窗口可能在桌面上包含多个标签页。每个标签 页都是独立的“浏览上下文”(browsing context),每个上下文都有独立的window对象,并且相互之间互不干扰

可是窗口不老是和其它窗口彻底没有关系。一个窗口或标签页中的脚本能够打开新的窗口或标签页,当一个脚本这样作时,这样多个窗口或窗口与另外一个窗口文档之间就能够互操做。(13.6.2节讲解的同源策略约束)。本节1小节会介绍窗口的打开和关闭的更多内容。 

html文档常用<iframe>来嵌套多个文档。由它所建立的嵌套浏览上下文是用它本身的window对象所表示的。废弃的<frameset>和<frame>元素一样建立了一个嵌套的浏览上下文。每个<frame>都由一个独立的window对象表示。对于客户端javascript来讲,窗口、标签页、iframe和框架都是独立的浏览上下文。对于javascript来讲,它们都是window对象。和相互独立的标签页不一样,嵌套的浏览上下文之间并非相互独立的。在一个窗体中运行javascript程序老是能看见它的祖先和子孙窗体,尽管脚本查看这些窗体中的文档受到同源策略限制。14.8.2节。

由于window是客户端javascript的全局对象,每一个窗口或窗体都包含独立的javascript执行上下文。不过在一个窗口中的javascript代码,若有同源策略的限制,则可使用另一个窗口中定义的对象、属性和方法。与此相关的细节会在14.8.3节详细讨论。因为同源策略的限制致使窗口之间没法直接交互时,html5提供了一个基于事件的消息传输API,能够用于间接通讯。22章3节会讨论。

8.1.打开和关闭窗口

使用window对象的open()方法能够打开一个新的浏览器窗口(或标签页,这一般和浏览器的配置项有关)。window.open()载入指定的url到新的或已存在的窗口中,并返回表明那个窗口的window对象。它有四个可选的参数。

open()第一个参数是要在新窗口中显示的文档的url。若是省略(也能够是空字符串),那么会使用页面的URLabout:blank。

opne()第二个参数是新打开的窗口的名字。若是指定的是一个以及存在的窗口的名字(而且脚本容许跳转到那个窗口),会直接使用已经存在的窗口。不然,会打开新的窗口,并将这个指定的名字赋值给它。若是省略此参数,会使用指定的名字“_blank”打开新的、未命名的窗口。

须要注意的是,脚本是没法经过简单的猜想窗口的名字来控制操纵这个窗口中的web应用的,只有设置了“容许导航”(allowed to navigte)(html5规范术语)的页面才能够这样。宽泛的讲,当且仅当窗口包含的文档来自相同的源或者是这个脚本打开了那个窗口(或者是递归地打开了窗口中打开的窗口),脚本才能够经过名字来指定存在的窗口。还有,若是其中一个窗口是内嵌在另外一个窗口的里的窗体,那么它们的脚本直接就能够相互导航。在这种状况下,可使用保留的名字“_top”(顶级祖先窗口)和“_parent”(直接父级窗口)来获取彼此浏览上下文。

open()的第三个可选参数是一个以逗号分隔的列表,包含大小和各类属性,用以代表新窗口是如何打开的。若是省略它,新窗口会用一个默认的大小,并且带有一整组标准的UI组件,即菜单栏/状态栏、工具栏等。在标签式浏览器中,会建立一个新的标签。

另一方面,若是指定这个参数,就能够指定窗口的尺寸,以及它包含的一组属性。(显式指定窗口支持更像是建立新窗口,而不是新标签)例如,容许打开改变大小的浏览器窗口,而且包含状态栏、工具栏,地址栏能够这样写:

var w =window.open("smaillwin.html","smallwin","width=400,heigth=500,status=yes,resizeable=yes");

第三个参数是非标准的,html5规范也主张浏览器应该忽略它。参见第四部分中的window.open()查看在此参数中能够指定什么内容。注意,当指定第三个参数时,全部没有显式指定的功能都会忽略。出于各类安全缘由,浏览器包含对可能指定的功能的限制。例如:一般不容许指定一个过小或者位于屏幕以外才窗口,而且浏览器不容许建立一个没有状态栏的窗口。

open()的第四个参数只在第二个参数命名的是一个存在的窗口时才有用。它是一个布尔值,声明了由第一个参数是url是应用替换掉窗口浏览历史的当前条目(true),仍是应该在窗口浏览历史中建立一个新的条目false,后者为默认设置。

open()的返回值是表明命名或新建立的窗口的window对象。能够在本身的javascript代码中使用这个window对象来引用新建立的窗口,就像使用隐式的window对象window来引用运行代码的窗口同样。

var w = window.open();
w.alert("to example.com");
w.location = "http://www.example.com"

在由window.open()方法建立的窗口中,opener属性引用的是打开它的脚本的window对象。在其它窗口中,opener为null:

w.opner !== true; //true, 对于任何由w建立的任意窗口
w.open().opener === w; //true,对于任意窗口w

window.open()是广告商用来在你浏览网页时采用的“页面以前弹出”或“页面以后弹出”窗口的一种方法。因为这种方法的滥用,大部分浏览器增长了弹出窗口过滤系统,一般,open()方法只有当用户单击按钮或者连接的时候才会调用,javascript代码尝试在浏览器载入或关闭时开启弹出一个窗口时,一般会失败。将上面的代码粘贴到浏览器javascript控制台进行测试 ,可能会由于一样的缘由而失败。

关闭窗口

就像方法open()打开一个新窗口同样,方法close()将关闭一个窗口。若是已经建立了window对象w,可使用以下的代码将它关闭。

w.close()

运行在那个窗口中的javascript代码则可使用下面的代码关闭。以下

window.close();

注意,要显式地使用标识符window。这样能够避免混淆window对象的close()方法和Document对象的close()方法,若是正在从事件处理程序调用close()。这很重要

大多浏览器只容许自动关闭由本身的javascript代码建立的窗口。若是要关闭其余窗口,能够用一个对话框提示用户,要求他对关闭窗口的请求进行确认或取消。在表示窗体而不是顶级窗口或标签页上的window对象执行close()方法不会有任何效果,它不能关闭一个窗体(反之能够从它包含的文档中删除iframe)。

即便一个窗口关闭了,表明它的window对象仍然存在。已关闭的窗口会有个值为为true的closed属性。它的Document会是null。它的方法一般不再会工做。

8.2.窗体之间的关系

咱们已经知道,window对象的方法open()返回表明新建立的窗口的window对象,并且这个新窗口具备opener属性,该属性能够打开它的原始窗口。这样,两个窗口就能够相互引用,彼此均可以读取对方的属性或是调用对方的方法。窗体也是这样的,窗口或窗体中运行的代码均可以经过下面介绍的属性引用到本身的窗口或窗体,以及嵌套的子窗体。

任何窗口或窗体中的javascript代码均可以将本身的窗口和窗体引用为window或self.窗体能够用parent属性引用包含它的窗口或窗体的window对象。

parent.history.back();

若是一个窗口是顶层窗口或标签,而不是窗体,那么其parent属性引用的就是这个窗口自己。

parent == self; //只有顶级窗口才会返回true

若是一个窗体包含在另外一个窗体中,然后者又包含在顶级窗口中,那么该窗体就可使用parent.parent来引用顶级窗口。top属性是一个通用的快捷方式,不管一个窗体被嵌套了几层,它的top属性引用的都是指向包含它的顶级窗口。若是一个window对象表明的是一个顶级窗口,那么它的top属性引用的就是窗口自己。对于那些顶级窗口的直接子窗口,top属性就等价于parent属性。

parent和top属性容许脚本引用它的窗体的祖先。有不止一种方法能够引用窗口或窗体的子孙窗体。窗体是经过iframe元素建立的。能够用 获取其余元素的一个方法获取一个表示iframe元素的对象。假定文档里有<iframe id="f1">,那么表示该iframe元素的对象就是:

var iframeElement = document.getElementById("f1");

<iframe>元素有contentWindow属性,引用该窗体的window对象,因此此窗体的window对象就是:

 var childFrame = document.getElementById("f1").contentWindow;

能够进行反向操做——从表示窗体的window对象来获取该窗体的<iframe>元素,用window对象的frameElement属性。表示顶级窗口的window对象的frameElement属性为null。窗体中的window对象的frameElement属性不是null:

var elt = document.getElementById("f1");
var win = elt.contentWindow;
win.frameElement === elt; //对于帧来讲,永远是true
window.frameElement === null; //对于顶级窗口来讲,永远是true

。。。。。。

8.3.交互窗口中的javascript

每一个窗口和窗体都是它自身的javascript执行上下文,以window做为全局对象。可是若是一个窗口或窗体中的代码能够应用到其余窗口或窗体(而且同源策略没有阻止它),那么一个窗口或窗体中的脚本就能够和其它窗口或窗体的脚本进行交互。

设想一个web页面中有两个<iframe>元素 ,分别叫A和B,而且这些窗体所包含的文档来自同一服务器,而且包含交互脚本,窗体A里的脚本定义了一个变量i :

var i = 3;

这个变量只是全局对象的一个属性,也是window对象的一个属性。窗体A中的代码能够用标识符i来引用变量,或者用window对象显式的引用这个变量:

window.i

因为窗体B中的脚本能够引用窗体A的window对象,所以它能够引用那个window对象的属性:

parent.A.i=4;//改变窗体A中的变量i的值

。。。。。。

相关文章
相关标签/搜索