JavaScript基础:window对象与DOM树形结构详解
本文深入解析JavaScript中的window对象及其丰富的属性与方法,重点讲解onbeforeunload事件在不同浏览器(IE、Chrome、Firefox)中的兼容性与实现细节。随后介绍DOM的核心概念,阐述文档对象模型如何以树形结构表示HTML,并通过节点类型、父子节点操作及动态添加删除元素的代码示例,展示如何利用DOM控制页面内容。
window对象属性与事件
window对象的属性十分丰富,为了节省篇幅,这里直接引用手册中的部分内容:
| closed | 获取引用窗口是否已关闭。 |
| defaultStatus | 设置或获取要在窗口底部的状态栏上显示的缺省信息。 |
| dialogArguments | 设置或获取传递给模式对话框窗口的变量或变量数组。 |
| dialogHeight | 设置或获取模式对话框的高度。 |
| dialogLeft | 设置或获取模式对话框的左坐标。 |
| dialogTop | 设置或获取模式对话框的顶坐标。 |
| dialogWidth | 设置或获取模式对话框的宽度。 |
| frameElement | 获取在父文档中生成 window 的 frame或 iframe 对象。 |
| length | 设置或获取集合中对象的数目。 |
| name | 设置或获取表明窗口名称的值。 |
| offscreenBuffering | 设置或获取对象在对用户可见之前是否要先在屏幕外绘制。 |
| opener | 设置或获取创建当前窗口的窗口的引用。 |
| parent | 获取对象层次中的父窗口。 |
| returnValue | 设置或获取从模式对话框返回的值。 |
| screenLeft | 获取浏览器客户区左上角相对于屏幕左上角的 x 坐标。 |
| screenTop | 获取浏览器客户区左上角相对于屏幕左上角的 y 坐标。 |
| self | 获取对当前窗口或框架的引用。 |
| status | 设置或获取位于窗口底部状态栏的信息。 |
| top | 获取最顶层的祖先窗口。 |
上述内容仅列举了window的部分属性,它还包含大量事件和方法。此处不再赘述,旨在提醒读者:当需要实现特定效果却不知如何下手时,不妨先查阅window类,它很可能已封装了所需功能。
body元素作为以下window对象事件的宿主:onblur、onbeforeunload、onfocus、onload和onunload。
接下来,我们利用window对象实现一个页面离开时的提示功能。
通常我们需要在用户离开页面时进行确认,例如询问是否确认离开。实际上,只需在body节点添加相关代码即可实现。
<body onbeforeunload="return 'Are you exiting?'">
添加上述代码后,用户尝试关闭或离开页面时将弹出提示框。
在该示例中,需注意以下三个关键点:
必须使用return语句返回字符串(如return 'xxxxx'),分号可选。如果仅返回字符串而不使用return,则不会触发提示。
此前已强调过,由于onbeforeunload事件属性值本身使用双引号包裹,因此内部的return语句必须使用单引号包裹字符串,否则会导致语法错误。
该写法在Firefox、Chrome和IE浏览器中均有效。其中Chrome和IE的触发机制相似,表现一致:在确认栏中显示返回的字符串。推测其执行流程为:用户点击关闭按钮触发onbeforeunload事件,若返回值是字符串,则向上触发警告并显示该字符串。然而Firefox的行为不同,它仅显示默认的警告信息,不显示自定义字符串。
在Chrome浏览器中,提示效果如下:

返回的字符串显示在导航栏上方,与IE的效果一致(若IE未显示,点击“允许运行脚本”即可)。对于Firefox,仅显示上层的默认提示,与代码中返回的字符串无关。尽管如此,代码中仍需保留该语句,否则Firefox将完全不显示任何提示。

若希望确认框中显示自定义内容,经过多次尝试发现,Firefox无法通过其他对话框替代其默认提示框。因此,我们只能额外添加一个confirm对话框,但这会导致Firefox出现两次提示。IE和Chrome则能在离开提示中正确显示函数返回的字符串,表现较好。以下是根据反馈修改后的代码。
测试表明,该代码在Chrome 16.0.912.0版本中仅显示一次提示。但在某些基于Chrome内核的浏览器(如Sunchrome)中,可能出现类似Firefox和Chrome的双重提示现象。推测原因可能是这些浏览器混合了其他内核,具体机制尚不明确。
综上所述,建议采用全兼容方案。
具体代码如下:
<html>
<head>
<title>testing</title>
<script type="text/javascript" src="js/output.js"></script>
<script language="javascript" for ="window" EVENT ="onbeforeunload">//for IE
return "Sure to exit?(IE)"//如果返回字符串, 就会提示是否留在页面
// 如果没有这个节点,会显示Chrome的提示框
</script>
<script type="text/javascript" >
function closing(){
var res=confirm("Are you exiting?(FF)"); //这个会在FF显示
return "Are you exiting?(chrome)"; //这个会在Chrome显示
}
</script>
</head>
<body onbeforeunload="return closing();">
testing
</body>
</html>上述代码中,若定义了该script节点,IE浏览器将执行此部分代码;若未定义,则在Firefox和Chrome中运行正常,但在IE中会出现双重提示(既执行window.confirm又返回Chrome提示字符串)。
以下是上述代码在各浏览器中的测试结果:

DOM树形结构与节点操作
哈哈,怎么样,不错吧~ 好,接下在就是万众期待(其实只有LZ期待吧= =+)的DOM DOM的全称是document object model,怎么理解这个东西挺关键的,我看了不少定义,有的说它是个平台,有的说它是个接口,anyway,我打开了它的官方guide网站:http://www.w3.org/DOM/ 它对DOM的定义是: The Document Object Model is a platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page. 我来简单翻译下好了:DOM是个平台/语言的中间接口,它可以允许程序和脚本动态的访问和更新内容、架构以及文件style。文件可以被进一步处理并将结果返回到显示页面。 其实这么说我看了也还是云里雾里,所以可以这么理解,DOM是个大家为了编程方便,传输速度快而统一起来的,基于树规范,它跟浏览器是没有关系的。DOM的基本思想就是树形结构,比如HTML文件,就是一个树形结构。DOM是没有跟任何语言绑定的,我们利用js可以对html dom进行动态的修改。 DOM有三个级别,可以分为:core Dom, XML DOM(*), HTML DOM三部分。中间那个是作为文档传输标准,使用很广泛的,但是这里就着重讲HTML DOM。 DOM把文档分为带有:元素、属性、文本 的树形结构,然后将这些作为结点来构造文档的树形结构,这样,就可以通过一个结点访问到所有的结点。 之前给出的那个网站(https://www.jb51.net/w3school/js/jsref_obj_string.htm)里面有比较全的DOM的玩意儿,可以用来参考,但是用来做教程还是有点生硬。 我打算先介绍节点类型,然后再对应到代码里。 节点类型介绍(复制来自https://www.jb51.net/w3schools/jsref/dom_obj_node.htm)
| Node type | Description | Children | Value | Constant |
|---|---|---|---|---|
| Element | Represents an element | Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference | 1 | ELEMENT_NODE |
| Attr | Represents an attribute | Text, EntityReference | 2 | ATTRIBUTE_NODE |
| Text | Represents textual content in an element or attribute | None | 3 | TEXT_NODE |
| CDATASection | Represents a CDATA section in a document (text that will NOT be parsed by a parser) | None | 4 | CDATA_SECTION_NODE |
| EntityReference | Represents an entity reference | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference | 5 | ENTITY_REFERENCE_NODE |
| Entity | Represents an entity | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference | 6 | ENTITY_NODE |
| ProcessingInstruction | Represents a processing instruction | None | 7 | PROCESSING_INSTRUCTION_NODE |
| Comment | Represents a comment | None | 8 | COMMENT_NODE |
| Document | Represents the entire document (the root-node of the DOM tree) | Element, ProcessingInstruction, Comment, DocumentType | 9 | DOCUMENT_NODE |
| DocumentType | Provides an interface to the entities defined for the document | None | 10 | DOCUMENT_TYPE_NODE |
| DocumentFragment | Represents a "lightweight" Document object, which can hold a portion of a document | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference | 11 | DOCUMENT_FRAGMENT_NODE |
| Notation | Represents a notation declared in the DTD | None | 12 | NOTATION_NODE |
了解基本概念后,我们通过一个简单的HTML文件来观察DOM的树形结构:HTML文本
代码如下:
<html>
<head>
<title>DOMcheck</title>
</head>
<body>
<a herf="#">click here</a>
<br>
<input type="test" id="in"></input>
<input type="button" id="but" value="here~"></input>
<body>
</html> 树形结构解析

注:理论上br标签可能不是节点,但不确定,望知情者指正。
1. 文档始终是根节点,获取document节点可直接使用document.documentElement或document.body。
2. script标签也是节点,凡是用<>包裹的内容均为节点,包括注释。
3. 节点名称(如head、title等)对应节点的tagName属性。
从一个节点获取其他节点的方法无非向上、向下或平行三个方向,具体可查阅前述网站中DOM Node对象的属性和方法(部分功能在IE中不可用,需测试后决定使用方式)。
大致了解DOM节点的各种方法后,我们进行一个小应用:
用户点击时,可添加或折叠子选项。
代码如下:
<html>
<head>
<title>DOM check</title>
<script type="text/javascript" >
var ifopen=false;
function get(element){
return document.getElementById(element);
}
function crea(element){
return document.createElement(element);
}
function openlist(){
var titl=get("chapter1");
if(get("sub1")==null){
var s=crea("span")
s.setAttribute("id","sub1");
}
else
s=get("sub1");
ifopen=!ifopen;
if(ifopen){ // 没打开的话
s.innerHTML="<br><a href='#L1' >list1</a>"+
"<br><a href='#L2' >list2</a>"+"<br><a href='#L3' >list3</a>";
titl.appendChild(s);
}else{
var de= document.getElementById("sub1");
de.parentNode.removeChild(de) ;
}
}
</script>
</head>
<body >
<span id="chapter1">
<a href="#" id="chaptername1" onclick="openlist()">chapter 1</a>
</span>
<br><br><br><br>
<span name="L1">
<p>babababababbabbaba</p>
</span>
<span name="L2">
<p>babababababbabbaba</p>
</span>
<span name="L3">
<p>babababababbabbaba</p>
</span>
<body>
</html> 各浏览器测试均无误。

当然,此效果可通过多种方法实现,此处仅为演示如何通过DOM控制NODE。
补充说明:节点除了添加和删除外,还可以克隆,函数为cloneNode。除setAttribute外,也可附加事件,例如节点已有onclick事件,可使用addEvent函数实现。具体细节不再赘述,原理相同。
anime.js 快速入门:怎么引入库并编写第一个 DOM 动画
2026-11-05 14:22:43
在线JS解密后变量名仍乱码?结合浏览器DevTools调试还原
2026-11-04 20:26:01
怎么在浏览器中运行JavaScript代码并查看输出结果
2026-11-04 09:07:33
JS 获取屏幕分辨率:window.screen.width 与 height 用法
2026-11-04 08:52:48
为什么推荐用DOMContentLoaded代替window.onload初始化JS
2026-11-04 08:42:33
