共计 4222 个字符,预计需要花费 11 分钟才能阅读完成。
1.window.requestIdleCallback()
window.requestIdleCallback(callback[, options])
callback 参数是一个回调函数。该回调函数执行时,系统会传入一个 IdleDeadline 对象作为参数。IdleDeadline 对象有一个 didTimeout 属性(布尔值,表示是否为超时调用)和一个 timeRemaining()方法(返回该空闲时段剩余的毫秒数)
options 参数是一个配置对象,目前只有 timeout 一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选
requestIdleCallback(myNonEssentialWork);
function myNonEssentialWork(deadline) {
while (deadline.timeRemaining() > 0) {
doWorkIfNeeded();
}
}
上面代码中,requestIdleCallback()用来执行非关键任务 myNonEssentialWork。该任务先确认本次空闲时段有剩余时间,然后才真正开始执行任务
下面是指定 timeout 的例子。
requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000});
上面代码指定,processPendingAnalyticsEvents 必须在未来 2 秒之内执行
如果由于超时导致回调函数执行,则 deadline.timeRemaining()返回 0,deadline.didTimeout 返回 true。
如果多次执行 window.requestIdleCallback(),指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。
事件
window 对象可以接收以下事件。
4.1load 事件和 onload 属性
load 事件发生在文档在浏览器窗口加载完毕时。window.onload 属性可以指定这个事件的回调函数
window.onload = function() {
var elements = document.getElementsByClassName(‘example’);
for (var i = 0; i < elements.length; i++) {
var elt = elements[i];
// ...
}
};
上面代码在网页加载完毕后,获取指定元素并进行处理。
4.2error 事件和 onerror 属性
浏览器脚本发生错误时,会触发 window 对象的 error 事件。我们可以通过 window.onerror 属性对该事件指定回调函数。
window.onerror = function (message, filename, lineno, colno, error) {
console.log(“ 出错了!–> %s”, error.stack);
};
由于历史原因,window 的 error 事件的回调函数不接受错误对象作为参数,而是一共可以接受五个参数,它们的含义依次如下。
出错信息
出错脚本的网址
行号
列号
错误对象
老式浏览器只支持前三个参数
并不是所有的错误,都会触发 JavaScript 的 error 事件(即让 JavaScript 报错)。
一般来说,只有 JavaScript 脚本的错误,才会触发这个事件,而像资源文件不存在之类的错误,都不会触发。
下面是一个例子,如果整个页面未捕获错误超过 3 个,就显示警告。
window.onerror = function(msg, url, line) {
if (onerror.num++ > onerror.max) {
alert('ERROR:' + msg + '\n' + url + ':' + line);
return true;
}
}
onerror.max = 3;
onerror.num = 0;
需要注意的是,如果脚本网址与网页网址不在同一个域(比如使用了 CDN),浏览器根本不会提供详细的出错信息,只会提示出错,错误类型是“Script error.”,行号为 0,其他信息都没有。这是浏览器防止向外部脚本泄漏信息。
一个解决方法是在脚本所在的服务器,设置 Access-Control-Allow-Origin 的 HTTP 头信息。
Access-Control-Allow-Origin: *
然后,在网页的 <script> 标签中设置 crossorigin 属性。
<script crossorigin=”anonymous” src=”//example.com/file.js”></script>
上面代码的 crossorigin=”anonymous” 表示,读取文件不需要身份信息,即不需要 cookie 和 HTTP 认证信息。如果设为 crossorigin=”use-credentials”,就表示浏览器会上传 cookie 和 HTTP 认证信息,同时还需要服务器端打开 HTTP 头信息 Access-Control-Allow-Credentials
4.3window 对象的事件监听属性
除了具备元素节点都有的 GlobalEventHandlers 接口,window 对象还具有以下的事件监听函数属性。
window.onafterprint:afterprint 事件的监听函数。
window.onbeforeprint:beforeprint 事件的监听函数。
window.onbeforeunload:beforeunload 事件的监听函数。
window.onhashchange:hashchange 事件的监听函数。
window.onlanguagechange: languagechange 的监听函数。
window.onmessage:message 事件的监听函数。
window.onmessageerror:MessageError 事件的监听函数。
window.onoffline:offline 事件的监听函数。
window.ononline:online 事件的监听函数。
window.onpagehide:pagehide 事件的监听函数。
window.onpageshow:pageshow 事件的监听函数。
window.onpopstate:popstate 事件的监听函数。
window.onstorage:storage 事件的监听函数。
window.onunhandledrejection:未处理的 Promise 对象的 reject 事件的监听函数。
window.onunload:unload 事件的监听函数。
5. 多窗口操作
由于网页可以使用 iframe 元素,嵌入其他网页,因此一个网页之中会形成多个窗口。如果子窗口之中又嵌入别的网页,就会形成多级窗口。
各个窗口之中的脚本,可以引用其他窗口。浏览器提供了一些特殊变量,用来返回其他窗口。
- top:顶层窗口,即最上层的那个窗口
- parent:父窗口
- self:当前窗口,即自身
与这些变量对应,浏览器还提供一些特殊的窗口名,供 window.open()方法、标签、<form> 标签等引用。
_top:顶层窗口
_parent:父窗口
_blank:新窗口
下面代码就表示在顶层窗口打开链接。
Link
5.1. 窗口的引用
5.2.iframe 元素 通过元素得到它的 window 对象
(同源才可)
对于 iframe 嵌入的窗口,document.getElementById 方法可以拿到该窗口的 DOM 节点,然后使用 contentWindow 属性获得 iframe 节点包含的 window 对象。
var f1Element = document.getElementById(‘f1’);
var f1Window = f1Element.contentWindow;
f1Window.frameElement === f1Element // true
window.frameElement === null // true
var frame = document.getElementById(‘theFrame’);
var frameWindow = frame.contentWindow;
上面代码中,frame.contentWindow 可以拿到子窗口的 window 对象。然后,在满足同源限制的情况下,可以读取子窗口内部的属性。
// 获取子窗口的标题
frameWindow.title
<iframe> 元素的 contentDocument 属性,可以拿到子窗口的 document 对象。
var frame = document.getElementById(‘theFrame’);
var frameDoc = frame.contentDocument;
// 等同于
var frameDoc = frame.contentWindow.document;
<iframe> 元素遵守同源政策,只有当父窗口与子窗口在同一个域时,两者之间才可以用脚本通信,否则只有使用 window.postMessage 方法
<iframe> 窗口的 window 对象,有一个 frameElement 属性,返回 <iframe> 在父窗口中的 DOM 节点。对于非嵌入的窗口,该属性等于 null。
5.3.window.frames 属性 通过属性得到
window.frames 属性返回一个类似数组的对象,成员是所有子窗口的 window 对象
比如,frames[0]返回第一个子窗口,frames[1].frames[2]返回第二个子窗口内部的第三个子窗口,parent.frames[1]返回父窗口的第二个子窗口。
注意,window.frames 每个成员的值,是框架内的窗口(即框架的 window 对象),而不是 iframe 标签在父窗口的 DOM 节点。如果要获取每个框架内部的 DOM 树,需要使用 window.frames[0].document 的写法
另外,如果 <iframe> 元素设置了 name 或 id 属性,那么属性值会自动成为全局变量,并且可以通过 window.frames 属性引用,返回子窗口的 window 对象。
// HTML 代码为 <iframe id=”myFrame”>
window.myFrame // [HTMLIFrameElement]
frames.myframe === myFrame // true
另外,name 属性的值会自动成为子窗口的名称,可以用在 window.open 方法的第二个参数,或者和 <frame> 标签的 target 属性。