本文详细解析JavaScript BOM中的window对象,阐述其作为全局对象的角色及全局作用域特性。深入探讨窗口位置、大小获取的跨浏览器兼容方案,以及窗口移动与调整API的使用限制。同时涵盖open方法参数、setTimeout与setInterval调度机制及系统对话框交互,提供完整的代码示例与注意事项。
BOM与window对象概述
ECMAScript构成了JavaScript语言的核心规范,但在Web开发环境中,真正驱动浏览器交互的核心组件是BOM(浏览器对象模型)。
BOM的核心在于window对象,它代表了浏览器中当前打开的一个具体实例。
在浏览器环境中,window对象具有双重身份:它既是JavaScript访问浏览器窗口的接口,也是ECMAScript规范中定义的Global(全局)对象。这意味着,在网页脚本中定义的任何变量、对象或函数,默认情况下都是window对象的属性或方法。
全局作用域特性
1. 全局作用域特性
由于window对象充当Global对象的角色,所有在全局作用域中声明的变量、对象和函数,都会自动成为window对象的属性和方法。
需要注意的是,通过全局作用域声明的变量与直接在window对象上定义的属性存在关键差异:全局变量无法通过delete操作符删除,而直接添加到window对象上的属性则可以。
var age=28;
window.color="red";
//在IE<9是抛出错误,在其他浏览器中都返回false
delete window.age;
//在IE<9是抛出错误,在其他浏览器中都返回true
delete window.color; //return true
alert(window.age); //28
alert(window.color); //undefined
当使用var语句向window添加属性时,该属性会被赋予一个名为[[Configurable]]的内部特性,其值被设置为false。这一机制导致通过var定义的全局变量无法使用delete操作符进行删除。
直接访问未声明的变量会引发ReferenceError错误,但通过查询window对象的属性,可以安全地判断某个可能未声明的变量是否存在,而不会抛出异常。
//这里抛出错误,因为oldValue未声明
var newValue=oldValue;
//这里不会抛出错误,因为这是一次属性查询
var newValue=window.oldValue // alert(newValue); //undefined
许多全局JavaScript内置对象,如location和navigator,实际上都是window对象的属性。
窗口关系及框架操作
2. 窗口关系及框架操作
如果页面中嵌入了框架(frameset),每个框架都拥有独立的window对象,这些对象被保存在window.frames集合中。
在frames集合中,可以通过数值索引或框架名称来访问特定的window对象。
<html>
<head>
<title>Frameset Example</title>
</head>
<frameset rows="160,*">
<frame src="frame.htm" name="topFrame">
<frameset cols="50%,50%">
<frame src="anotherframe.htm" name="leftFrame">
<frame src="yetanotherframe.htm" name="rightFrame">
</frameset>
</frameset>
</html>
例如,可以通过window.frames[0]或window.frames["topFrame"]来引用顶部的框架。然而,推荐使用top.frames[0]这种方式来访问框架,以确保引用的准确性。
top对象始终指向最高层(最外层)的框架,即当前的浏览器窗口。利用top对象可以确保在嵌套框架中正确访问其他框架。
与top对象相对的是parent对象,它始终指向当前框架的直接父级框架。
此外还有self对象,它始终指向当前的window对象。实际上,self和window可以互换使用,引入self主要是为了在语义上与top和parent保持对应关系。
上述所有对象(top、parent、self)均为window对象的属性,可以通过window.top或window.parent等方式直接访问。
窗口位置控制
3. 窗口位置控制
多数现代浏览器提供了screenLeft和screenTop属性,分别用于表示窗口相对于屏幕左侧和顶部的坐标位置。Firefox在screenX和screenY属性中提供相同的信息,而Safari和Chrome同时支持这两组属性。
为了实现跨浏览器获取窗口左侧和顶部的坐标,可以使用以下代码逻辑:
var leftPos=(typeof window.screenLeft=="number")?window.screenLeft:window.screenX;
var topPos=(typeof window.screenTop=="number")?window.screenTop:window.screenY;
值得注意的是,在IE和Opera浏览器中,screenLeft和screenTop存储的是从屏幕边缘到window对象所表示的页面可见区域的距离。而在Chrome、Firefox和Safari中,screenX和screenY存储的是整个浏览器窗口相对于屏幕的坐标值。
由于上述差异,无法在跨浏览器环境下精确获取窗口左侧和顶部的绝对坐标值。
不过,可以使用moveTo()和moveBy()方法将窗口精确移动到新位置。这两个方法均接收两个参数:moveTo()接收x和y轴的坐标值,moveBy()接收移动的像素距离。
//将屏幕移动到左上方
moveTo(0,0);
//将窗口左移50px
moveBy(-50,0);
然而,这两个方法可能会被浏览器安全策略禁用。此外,它们仅适用于最外层的window对象,不适用于框架内的窗口。
窗口尺寸获取
4. 窗口尺寸获取
主流浏览器提供了四个属性来确定窗口大小:innerWidth、innerHeight、outerWidth和outerHeight。
在IE9+、Safari和Firefox中,outerWidth和outerHeight返回的是浏览器窗口本身的尺寸(无论从哪个框架访问)。在Opera中,这两个属性的值表示页面视图容器的大小(即单个标签页窗口的大小)。而innerWidth和innerHeight则表示该容器中页面视图的大小(减去边框宽度)。在Chrome中,这四个属性均表示视口大小而非整个浏览器窗口的大小。
IE9之前的版本未提供直接获取浏览器窗口尺寸的属性,但通过DOM可以获取页面可视区域的信息。
在IE、Firefox、Chrome、Opera和Safari中,document.documentElement.clientWidth和document.documentElement.clientHeight保存着页面视口信息。在IE6中,这仅在标准模式下有效;如果是混杂模式,则必须通过document.body.clientWidth和document.body.clientHeight获取相同信息。Chrome则不区分标准模式或混杂模式。
虽然无法直接确定浏览器窗口本身的精确大小,但可以可靠地获取页面视口的大小。
var pageWidth = window.innerWidth,
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;
}
}
alert("Width: " + pageWidth);
alert("Height: " + pageHeight);
对于移动设备,window.innerWidth和window.innerHeight保存着可见视口的大小,即屏幕上页面区域的大小。移动版的IE浏览器则需要通过document.documentElement.clientWidth和document.documentElement.clientHeight来获取相同信息。
可以使用resizeTo()和resizeBy()方法来调整浏览器窗口的大小。这两个方法均接收两个参数:resizeTo()接收新窗口的宽度和高度,resizeBy()接收新窗口与旧窗口的宽度和高度差值。
//调整到100*100
resizeTo(100,100);
//调整到200*150
moveBy(100,50);
同样,这两个方法可能会被浏览器禁用,且仅适用于最外层的window对象,不适用于框架。
导航和打开窗口
5. 导航和打开窗口
window.open()方法既可以打开特定的URL,也可以创建一个新的浏览器窗口。该方法接收四个参数:要加载的URL、窗口目标名称、一个包含窗口特性的字符串,以及一个布尔值表示新页面是否取代当前页面历史记录。
弹出窗口配置
各项参数说明
其中yes/no也可以使用1/0表示;pixelvalue为具体的数值,单位为像素。
参数名称、取值范围及说明如下表所示:
alwaysLowered | yes/no | 指定窗口隐藏在所有窗口之后
alwaysRaised | yes/no | 指定窗口悬浮在所有窗口之上
dependent | yes/no | 是否和父窗口同时关闭
directories | yes/no | Nav2和3的目录栏是否可见
height | pixelvalue | 窗口高度
hotkeys | yes/no | 在没有菜单栏的窗口中设置安全退出热键
innerHeight | pixelvalue | 窗口中文档的像素高度
innerWidth | pixelvalue | 窗口中文档的像素宽度
location | yes/no | 位置栏是否可见
menubar | yes/no | 菜单栏是否可见
outerHeight | pixelvalue | 设定窗口(包括装饰边框)的像素高度
outerWidth | pixelvalue | 设定窗口(包括装饰边框)的像素宽度
resizable | yes/no | 窗口大小是否可调整
screenX | pixelvalue | 窗口距屏幕左边界的像素长度
screenY | pixelvalue | 窗口距屏幕上边界的像素长度
scrollbars | yes/no | 窗口是否可有滚动栏
titlebar | yes/no | 窗口标题栏是否可见
toolbar | yes/no | 窗口工具栏是否可见
width | pixelvalue | 窗口的像素宽度
z-look | yes/no | 窗口被激活后是否浮在其它窗口之上
示例代码演示:
window.open('page.html','newwindow','height=100,width=400,top=0,left=0,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no')
脚本运行后,page.html将在新窗体newwindow中打开,宽度为100像素,高度为400像素,距离屏幕顶部0像素,距离屏幕左侧0像素,无工具条,无菜单条,无滚动条,不可调整大小,无地址栏,无状态栏。
间歇调用和超时调用机制
6. 间歇调用和超时调用机制
JavaScript是单线程语言,但允许通过设置超时值和间歇时间来调度代码在特定时刻执行。前者是在指定的时间过后执行代码,后者则是每隔指定的时间就调用一次。
超时调用setTimeout()方法接受两个参数:第一个参数是回调函数,第二个参数是时间(单位毫秒),该方法返回一个数值ID。
setTimeout( function () {
alert("你好!");
},1000);
调用setTimeout()后,该方法会返回一个数值ID,表示超时调用。可以通过该ID来取消超时调用。
var timeOutId = setTimeout( function () {
alert("你好!");
},1000);
clearTimeout(timeOutId);
间歇调用setInterval()方法
setInterval()方法接受两个参数:第一个参数是回调函数,第二个参数是时间(单位毫秒),该方法返回一个数值ID。
setInterval( function () {
alert("你好!");
},1000);
取消调用clearInterval(),该方法接受一个参数,即间歇调用的ID。
var intervalId = null;
var span = document.createElement("span"); //创建span节点
span.Id="time"; //设置span的id
document.body.appendChild(span); //body内添加span
function incrementNumber () {
var now = new Date();
var timeStr = now.toLocaleTimeString();
span.innerText =timeStr;
num++;
if (num == 10) {
clearInterval(intervalId); //十秒后时间不变了
}
}
intervalId = setInterval(incrementNumber,1000);
建议尽量使用超时调用(setTimeout)来替代间歇调用(setInterval),以避免累积误差。
var num = 0;
var max = 10;
function incrementNumber() {
num++;
if (num<max) {
setTimeout(incrementNumber,1000);
} else {
alert("OK");
}
}
setTimeout(incrementNumber,1000);
系统对话框交互
7. 系统对话框交互
警告框alert()用于显示警告信息。
alert("欢迎光临!");
信息框confirm()提供取消和确定按钮,用于确认用户操作。
if (confirm("你同意吗?")) {
alert("同意");
} else {
alert("不同意");
}
提示框prompt()用于提示用户输入一些文本,并返回用户输入的值。
var result = prompt("您尊姓大名?"," ");
if (result !== null) {
alert(“欢迎光临,”+result);
}
以上关于JavaScript BOM window对象的详解内容,旨在帮助开发者深入理解浏览器对象模型的核心机制。希望这些内容能为大家提供有价值的参考,也欢迎大家继续支持本站获取更多技术分享。