JavaScript Window对象 | 自在学
Window对象
Window对象作为浏览器JavaScript环境中的全局对象,既代表浏览器窗口本身,也是所有客户端脚本的顶级命名空间。
开发者通过Window对象能够访问、管理和控制页面中的各类资源与行为,包括但不限于定时与延时执行、页面导航、浏览器和操作系统信息获取、用户交互对话框管理等。
掌握Window对象的各项API,是开发高效、交互性强、兼容性优良的Web应用程序的基础。
定时器机制
在Web应用开发过程中,合理地控制代码的执行时机至关重要。比如,有时我们希望某些操作在页面加载后延迟一段时间再执行,
或者希望某个任务能够按照固定的时间间隔不断重复。
为此,JavaScript在Window对象中内置了定时器相关的功能,开发者可以通过这些API来实现对代码执行时序的精确把控。
无论是实现动画效果、定时轮询数据,还是延迟提示用户信息,定时器机制都为前端开发提供了极大的灵活性和便利性。
setTimeout:延迟执行
setTimeout函数允许我们在指定的时间延迟后执行一段代码。这个函数接受两个主要参数:要执行的函数和延迟的毫秒数。当指定的时间过去后,浏览器会自动调用我们提供的函数。
function showWelcomeMessage () {
console. log ( "欢迎访问我们的网站!" );
}
// 3秒后显示欢迎消息
setTimeout (showWelcomeMessage, 3000 );
// 也可以使用匿名函数
setTimeout ( function () {
console. log ( "页面加载完成,开始初始化用户界面" );
}, 1000 );
页面加载完成,开始初始化用户界面
欢迎访问我们的网站!
当我们调用setTimeout函数时,浏览器会返回一个唯一的定时器标识符(通常是一个数字)。这个标识符可以用作后续操作的凭据。
如果在定时器指定的延迟时间尚未到达之前,我们希望取消这次延迟执行,只需将这个标识符作为参数传递给clearTimeout函数即可。
这样,原本计划要执行的代码就不会被触发。
例如,在用户进行某些交互后,如果原定的操作已经没有必要执行,通过这种方式可以灵活地终止定时任务,避免不必要的逻辑执行或界面更新。
let messageTimer = setTimeout ( function () {
console. log ( "这条消息可能不会显示" );
}, 5000 );
// 如果用户在3秒内点击了按钮,就取消定时器
setTimeout ( function () {
clearTimeout (messageTimer);
console. log ( "定时器已被取消" );
}, 3000 );
定时器已被取消
setInterval:重复执行
在实际开发中,有些任务需要按照固定的时间间隔不断地执行,比如定时刷新页面数据、轮询服务器状态或者实现简单的计时器功能。
此时,可以使用setInterval函数来实现。setInterval会在每隔指定的毫秒数后自动调用一次我们提供的函数,这个过程会持续进行,直到我们通过clearInterval手动终止它为止。这样,开发者就能够方便地让某段代码周期性地运行,无需手动重复调用。
let seconds = 0 ;
function updateTimer () {
seconds ++ ;
console. log ( `计时器运行了 ${ seconds } 秒` );
// 在页面上更新显示(假设有一个id为timer的元素)
let timerElement = document. getElementById ( 'timer' );
if (timerElement) {
timerElement.textContent = `${ seconds } 秒` ;
}
}
计时器运行了 1 秒
计时器运行了 2 秒
计时器运行了 3 秒
...
计时器运行了 10 秒
计时器已停止
实际应用:动态内容更新
在实际开发中,定时器不仅可以用来延迟或重复执行某些操作,还能帮助我们实现动态更新的用户界面。例如,我们可以通过定时器不断获取当前的系统时间,并将其显示在页面上,从而实现一个能够实时显示当前时间的数字时钟。
下面将通过具体的代码演示,说明如何利用定时器机制来让页面内容随着时间自动变化,实现动态的视觉效果。
function createDigitalClock () {
function updateClock () {
let now = new Date ();
let timeString = now. toLocaleTimeString ( 'zh-CN' , {
hour12: false ,
hour: '2-digit' ,
minute: '2-digit' ,
second: '2-digit'
});
console. log ( `当前时间:${ timeString
当前时间:14:23:45
当前时间:14:23:46
当前时间:14:23:47
这个例子展示了定时器在创建动态用户界面方面的强大能力。通过合理使用setTimeout和setInterval,我们可以创建各种实时更新的功能,如动画效果、数据刷新、进度指示等。
页面位置与导航
Window对象的location属性是浏览器中用于管理和操作当前页面URL的关键接口。通过访问location属性,我们不仅能够读取当前页面的完整地址,还可以分别获取协议、主机名、端口、路径、查询参数和哈希等详细信息。
此外,location属性还允许我们通过修改其值来实现页面跳转,无论是刷新当前页面、导航到站内其他资源,还是重定向到外部网站,都可以通过对location的操作来完成。因此,location属性在实现页面导航、参数解析以及前端路由等场景中扮演着非常重要的角色。
理解Location对象
location属性指向一个Location对象,这个对象包含了当前页面URL的完整信息。我们可以通过它的各个属性来访问URL的不同部分:
function analyzeCurrentURL () {
// 假设当前URL是:https://www.example.com:8080/products/search?category=books&page=2#results
console. log ( "完整URL:" , location.href);
console. log ( "协议:" , location.protocol);
console. log ( "主机名:" , location.hostname);
console. log ( "端口:" , location.port);
console. log ( "路径:" , location.pathname);
console. log ( "查询参数:" , location.search);
console. log
完整URL: https://www.example.com:8080/products/search?category=books&page=2#results
协议: https:
主机名: www.example.com
端口: 8080
路径: /products/search
查询参数: ?category=books&page=2
片段标识符: #results
解析URL参数
在Web应用开发过程中,获取URL中的参数信息是非常常见的需求。每当用户访问一个带有查询字符串的页面时,这些参数通常用于控制页面内容、筛选数据或实现分页等功能。
Location对象的search属性会返回当前URL中问号后面的所有内容,也就是查询字符串部分。我们可以通过对这个字符串进行处理,将其中的每一组参数名和参数值提取出来,并以键值对的形式组织,方便后续在代码中直接访问和使用这些参数。
function parseURLParameters () {
// 获取查询字符串(去掉开头的问号)
let queryString = location.search. substring ( 1 );
let parameters = {};
if (queryString) {
// 按&符号分割参数对
let pairs = queryString. split ( '&' );
pairs. forEach ( function ( pair ) {
// 查找等号的位置
let
URL参数: {category: "books", page: "2"}
商品类别: books
当前页码: 2
页面导航
Location对象除了能够读取和解析当前页面的URL信息,还具备控制页面跳转和导航的能力。通过直接修改location对象的相关属性,或者调用其内置的方法,可以让浏览器加载新的页面、刷新当前页面,或者在不保留历史记录的情况下进行跳转。这些操作为开发者提供了灵活的页面导航手段,能够根据不同的业务需求实现用户在站点内外的流畅切换。
function navigateToPage () {
// 方法1:直接设置新的URL
// location.href = "https://www.example.com/new-page.html";
// 方法2:使用assign方法
// location.assign("https://www.example.com/new-page.html");
// 方法3:使用replace方法(不会在历史记录中留下当前页面)
// location.replace("https://www.example.com/new-page.html");
// 方法4:重新加载当前页面
// location.reload();
console. log ( "准备跳转到新页面" );
}
// 智能导航函数
function smartNavigate ( url , replaceHistory = false ) {
if
浏览器支持现代功能,继续使用当前页面
浏览器历史管理
在Web浏览体验中,历史记录功能扮演着极为重要的角色。通过Window对象的history属性,开发者可以编程方式访问和操作浏览器维护的历史记录,从而实现页面的前进、后退以及跳转等导航行为。利用这一接口,网页能够根据用户的操作或程序逻辑灵活地控制浏览历史,提升用户的交互体验。
History对象基础
history属性是window对象的一个成员,它返回一个History对象,用于表示当前窗口的浏览历史。通过这个对象,开发者可以实现页面的前进、后退和跳转等导航操作。不过,出于用户隐私和安全的考虑,JavaScript无法直接读取历史记录中每一项的具体URL地址,只能通过提供的方法来控制历史的移动和管理。
function exploreHistory () {
// 获取历史记录的长度
console. log ( "历史记录条数:" , history. length );
// 注意:我们无法访问具体的URL地址
// 这是为了保护用户的隐私
}
// 历史导航函数
function navigateHistory () {
// 后退一页(等同于点击浏览器的后退按钮)
function goBack () {
history. back ();
console. log ( "执行后退操作" );
}
// 前进一页(等同于点击浏览器的前进按钮)
历史记录条数: 5
现代Web应用的历史管理
在现代Web应用开发中,页面内容的更新往往依赖于Ajax等技术实现局部刷新,而不是通过传统的整页跳转。这样一来,浏览器的历史记录不会自动反映用户在应用中的操作轨迹。为了让用户依然能够通过浏览器的前进和后退按钮在应用的不同状态之间切换,开发者需要通过编程方式维护应用的状态变化,并同步更新浏览器的历史记录。这通常涉及到在每次视图切换或状态变更时,主动调用相关API(如history.pushState或history.replaceState)来添加或修改历史记录,从而实现与原生页面跳转类似的导航体验。
// 模拟一个单页应用的历史管理
function createSPAHistoryManager () {
let currentView = 'home' ;
let viewHistory = [];
function changeView ( newView , addToHistory = true ) {
// 保存当前视图到历史记录
if (addToHistory && currentView !== newView) {
viewHistory. push (currentView);
}
currentView =
切换到视图: products
页面内容: 产品列表页面
历史记录: [home]
切换到视图: about
页面内容: 关于我们页面
历史记录: [home, products]
切换到视图: contact
页面内容: 联系我们页面
历史记录: [home, products, about]
切换到视图: about
页面内容: 关于我们页面
应用内后退成功
浏览器信息获取
在开发Web应用时,了解用户所使用的浏览器类型、版本、操作系统平台以及设备的屏幕参数,有助于我们针对不同环境进行兼容性优化和界面适配。浏览器为JavaScript提供了window.navigator和window.screen两个属性,前者包含了浏览器本身的详细信息,比如用户代理字符串、语言设置、平台类型、是否联网等,后者则提供了设备屏幕的分辨率、可用高度和宽度、色彩深度等参数。通过这些属性,开发者可以动态获取用户环境的相关数据,从而根据实际情况调整页面布局、功能实现或做出兼容性处理,提升用户体验和应用的稳定性。
Navigator对象详解
Navigator对象是浏览器为JavaScript提供的一个接口,通过它可以获取到浏览器的名称、版本、用户代理字符串、操作系统平台、语言设置、联网状态等丰富的信息。开发者可以利用这些属性来判断用户所用的浏览器类型、操作系统环境,甚至可以分析出设备的大致类别(如桌面端还是移动端)。虽然现代Web开发更强调通过检测具体功能是否可用来实现兼容性处理,而不是单纯依赖浏览器的类型判断,但在某些场景下,比如统计分析、定制化提示、针对特定浏览器的Bug修复或兼容性补丁等,获取这些浏览器相关的信息依然非常有价值。通过navigator对象,开发者能够动态了解用户的浏览器环境,从而做出更有针对性的适配和优化,提升Web应用的用户体验和稳定性。
function getBrowserInfo () {
let browserInfo = {
// 浏览器名称(注意:很多浏览器会伪装成其他浏览器)
name: navigator.appName,
// 浏览器版本信息
version: navigator.appVersion,
// 用户代理字符串(包含最详细的信息)
userAgent: navigator.userAgent,
// 操作系统平台
platform: navigator.platform,
// 浏览器语言
language: navigator.language,
// 在线状态
onLine: navigator.onLine
};
console. log ( "浏览器基本信息:"
浏览器基本信息:
name: Netscape
version: 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
platform: Win32
language: zh-CN
onLine: true
浏览器功能支持情况:
geolocation: 支持
cookiesEnabled: 支持
javaEnabled: 不支持
touchSupport: 不支持
localStorage: 支持
Screen对象和设备信息
screen对象是浏览器中用于获取用户显示器相关信息的接口。通过screen对象,可以获得当前显示器的分辨率、可用显示区域、颜色深度等参数。这些信息在开发网页时非常有用,尤其是在需要根据不同设备的屏幕尺寸和特性调整页面布局和样式时。利用screen对象,开发者能够判断用户所用设备的大致类型(如手机、平板、桌面电脑),从而动态调整界面,实现更好的用户体验和响应式设计。
function getScreenInfo () {
let screenInfo = {
// 屏幕总宽度和高度
totalWidth: screen.width,
totalHeight: screen.height,
// 可用宽度和高度(排除任务栏等)
availableWidth: screen.availWidth,
availableHeight: screen.availHeight,
// 颜色深度
colorDepth: screen.colorDepth,
// 像素深度
pixelDepth: screen.pixelDepth
};
console. log ( "屏幕信息:" );
for ( let key in
屏幕信息:
totalWidth: 1920
totalHeight: 1080
availableWidth: 1920
availableHeight: 1040
colorDepth: 24
pixelDepth: 24
设备类型: 桌面电脑或大屏幕设备
检测到大屏幕设备,使用桌面端布局
用户交互对话框
现代Web开发中,许多项目会采用自定义的模态对话框来实现更灵活的界面和交互效果。
然而,浏览器自带的对话框方法依然具备实际价值。
例如,在开发初期进行功能验证时,开发者可以快速弹出提示信息、
请求用户确认操作或收集简单输入,无需引入额外的UI库。这些内置对话框在调试、演示、或需要临时交互的场合下,能够大大提升开发效率,帮助开发者专注于核心逻辑的实现。
基础对话框方法
在浏览器中,可以通过三种内置方法与用户进行简单的交互。alert方法会弹出一个消息框,向用户显示提示信息,并且只有在用户点击“确定”后代码才会继续执行。
confirm方法会弹出一个带有“确定”和“取消”按钮的对话框,用于让用户确认某个操作,返回值为布尔类型,用户点击“确定”时返回true,点击“取消”时返回false。prompt方法则会弹出一个输入框,允许用户输入文本内容,开发者可以设置默认值,用户输入后点击“确定”会返回输入的字符串,点击“取消”则返回null。这些方法都属于window对象,可以直接调用,常用于调试、功能验证或临时收集用户信息。
function demonstrateBasicDialogs () {
// alert:显示信息
function showAlert () {
alert ( "欢迎使用我们的应用! \n 这是一个信息提示对话框。" );
console. log ( "信息对话框已显示" );
}
// confirm:获取确认
function getConfirmation () {
let userChoice = confirm ( "您确定要删除这个文件吗? \n 此操作无法撤销。" );
if (userChoice) {
console.
错误处理机制
在Web应用开发过程中,错误不可避免地会发生。为了提升用户体验和应用的健壮性,我们需要对这些错误进行有效的捕获和处理。浏览器中的Window对象为我们提供了全局的错误捕获能力。
通过设置window.onerror属性,我们可以在JavaScript代码运行时出现未被捕获的异常时,第一时间获取到错误信息,包括错误消息、出错的脚本文件、具体的行号和列号,以及错误对象本身。
这样不仅可以在前端及时反馈错误信息,还能将错误日志上传到服务器,便于后续的排查和修复,从而保障Web应用的稳定运行和用户的正常使用。
全局错误处理
onerror事件处理器是一种在浏览器端用于捕获页面中未被try...catch语句捕获的JavaScript运行时错误的机制。
当页面中的脚本发生错误时,onerror会被自动触发,并接收到错误的详细信息,包括错误消息、出错的脚本文件名、具体的行号和列号,以及错误对象本身。
function setupGlobalErrorHandler () {
// 设置全局错误处理器
window. onerror = function ( message , source , lineNumber , columnNumber , error ) {
console. log ( "捕获到JavaScript错误:" );
console. log ( `错误信息: ${ message }` );
console. log ( `错误源文件: ${ source }` );
console. log
全局错误处理器已设置
捕获到预期的测试错误: 这是一个测试错误
错误 #1: ReferenceError: undefinedFunction is not defined
正在将错误信息发送到服务器...
错误详情: {message: "ReferenceError: undefinedFunction is not defined", ...}
文档元素的全局访问
在浏览器环境中,Window对象具备一个独特的行为:当HTML文档中的某个元素设置了id属性时,浏览器会自动在Window对象上添加一个同名属性,这个属性会引用对应的DOM元素。
这样,开发者可以直接通过id名称在全局作用域访问该元素,无需显式调用document.getElementById。例如,如果页面上有一个id为mainContent的div元素,
那么在JavaScript代码中可以直接通过mainContent来访问和操作这个元素。
这种机制在实际开发中可以让代码更加简洁,减少查找元素的代码量。
然而,这种自动全局变量的生成也带来了一些潜在风险,比如id名称可能与Window对象已有的属性或方法发生冲突,导致无法正确访问元素或覆盖了原有的全局属性。
因此,在使用这一特性时需要格外注意id的命名,避免与标准的全局属性重名,并且在大型项目或多人协作时,建议优先采用document.getElementById等更为安全和明确的方式来获取元素。
自动全局变量
在浏览器中,如果HTML文档中的某个元素设置了id属性,浏览器会自动在全局的Window对象上添加一个与该id同名的属性,
这个属性会直接引用对应的DOM元素。这样,开发者可以在JavaScript代码中直接通过id名称访问该元素,
无需调用document.getElementById方法。
例如,页面上有一个id为"mainContent"的div元素时,
可以直接使用mainContent来获取和操作这个元素。不过需要注意,如果id的名称与Window对象已有的属性或方法发生冲突(比如id为"location"),这种自动创建的全局变量就不会生效,因此在命名id时要避免与标准全局属性重名。
// 假设HTML中有:<div id="mainContent">内容区域</div>
function demonstrateAutoGlobalVars () {
// 可以直接通过id访问元素(如果id没有与现有Window属性冲突)
if ( typeof mainContent !== 'undefined' ) {
console. log ( "找到主内容区域:" , mainContent.tagName);
console. log ( "元素内容:" , mainContent.textContent);
// 修改元素样式
mainContent.style.backgroundColor = "lightblue" ;
console. log ( "已修改元素背景色" );
} else {
找到主内容区域: DIV
元素内容: 内容区域
已修改元素背景色
安全地找到元素: DIV
元素存在性检查结果: {header: true, navigation: true, mainContent: true, footer: false}
找到元素: mainContent
未找到元素: sidebar
多窗口与框架
在现代Web开发中,应用程序往往不仅限于单一的浏览器窗口。开发者可能需要通过脚本打开新的窗口或标签页,实现多任务协作、弹出辅助界面,或者在父页面中嵌入iframe以加载其他网页内容,形成嵌套的浏览上下文。
每一个窗口或iframe都拥有自己的Window对象,这些对象之间可以通过特定的属性和方法进行交互。
例如,主窗口可以访问它所创建的子窗口的属性和方法,反之亦然,只要它们处于同源策略允许的范围内。通过Window对象,开发者能够实现窗口的打开、关闭、聚焦、消息传递等操作,从而灵活地管理和协调多个窗口或嵌套页面之间的关系。
这为构建复杂的Web应用提供了强大的支持,但同时也需要注意安全性和用户体验,避免滥用弹窗或跨域访问带来的问题。
窗口的打开与关闭
window.open方法可以用来在当前页面之外新建一个浏览器窗口或标签页。通过调用window.open并传入目标URL、窗口名称以及可选的特性参数,开发者能够在用户的浏览器中打开一个新的页面实例。
这种方式常用于弹出辅助界面、展示外部内容或实现多任务协作。
例如,当用户点击某个按钮时,可以通过window.open将相关信息在新窗口中展示,而不会影响当前页面的内容。
需要注意的是,浏览器通常会对弹窗行为进行限制,只有在用户交互(如点击)触发时才允许打开新窗口。
此外,window.open返回的新窗口对象可以被脚本进一步操作,比如聚焦、关闭或与主窗口进行通信,从而实现更灵活的窗口管理和页面间交互。
function createWindowManager () {
let openWindows = [];
// 打开新窗口
function openNewWindow ( url , name , features ) {
try {
let newWindow = window. open (url, name, features);
if (newWindow) {
openWindows. push ({
window: newWindow,
name: name,
url: url,
成功打开窗口: helpWindow
成功打开窗口: settingsWindow
当前打开的窗口数量: 2
窗口 1: helpWindow - help.html
窗口 2: settingsWindow - settings.html
iframe框架管理
iframe元素在网页中扮演着嵌套浏览上下文的角色,它能够让开发者在当前页面内部加载和显示其他独立的HTML文档。
通过这种方式,主页面和iframe中的内容可以实现一定程度的隔离,但又可以通过特定的API进行交互。
例如,主页面可以通过JavaScript动态创建iframe元素,设置其src属性来指定要加载的文档地址,并通过DOM操作将其插入到页面的指定位置。
当iframe加载完成后,可以通过iframe的contentWindow属性获取到其对应的window对象,从而实现主页面与iframe之间的数据通信和方法调用。
此外,主页面还可以使用postMessage方法向iframe发送消息,而iframe同样可以通过postMessage向父页面传递信息,这对于实现跨域通信和模块化开发非常有用。
function createIframeManager () {
// 创建iframe元素
function createIframe ( src , id , width = '100%' , height = '400px' ) {
let iframe = document. createElement ( 'iframe' );
iframe.src = src;
iframe.id = id;
iframe.style.width = width;
iframe.style.height = height;
开始监听iframe消息
iframe contentFrame 加载完成
iframe URL: content.html
获取到iframe contentFrame 的Window对象
向iframe contentFrame 发送消息: {type: "init", config: {theme: "light", language: "zh-CN"}}
Window对象是浏览器JavaScript编程的核心,它提供了丰富的API来控制浏览器的各个方面。从时间控制到页面导航,从信息获取到用户交互,Window对象的每个功能都有其特定的应用场景。
在现代Web开发中,虽然一些传统的API(如alert对话框)使用频率降低,但理解这些基础概念对于构建复杂的Web应用仍然很重要。特别是在处理多窗口应用或iframe集成时,深入理解Window对象的行为模式是必不可少的。
随着Web技术的不断发展,Window对象的功能也在持续演进。但是,本章介绍的核心概念和方法将为你学习更高级的浏览器API奠定坚实的基础。无论是处理用户交互、管理应用状态,还是创建复杂的用户界面,Window对象都将是你的重要工具。
习题
A. setTimeout
B. setInterval
C. clearTimeout
D. clearInterval
A. window.location.href
B. window.location.assign()
C. window.location.replace()
D. 以上都可以
A. history.length
B. history.back()
C. history.forward()
D. history.go()
A. navigator.userAgent
B. navigator.platform
C. navigator.language
D. 以上都是
A. alert()只能显示字符串
B. confirm()返回布尔值
C. prompt()可以获取用户输入
D. 以上都正确
创建一个简单的定时器示例,要求:
使用setTimeout创建一个延迟执行的定时器
使用setInterval创建一个重复执行的定时器
演示如何清除定时器
// 创建一个5秒后执行的定时器(只执行一次)
let timer1 = setTimeout ( function () {
console. log ( "定时器执行" );
alert ( "5秒后显示的消息" );
}, 5000 );
// 创建一个每2秒重复执行的定时器
let count = 0 ;
let timer2 = setInterval ( function () {
count ++ ;
console. log (
实现一个简单的页面跳转功能,要求:
获取当前页面的URL信息
实现页面跳转到新URL
使用不同的跳转方法
// 获取当前页面的URL信息
console. log ( "当前URL:" + window.location.href);
console. log ( "协议:" + window.location.protocol);
console. log ( "主机:" + window.location.host);
console. log ( "路径:" + window.location.pathname);
// 方法1:直接设置href(会在历史记录中留下记录)
function navigateToPage1 ( url ) {
window.location.href = url;
}
// 方法2:使用assign()方法(会在历史记录中留下记录)
创建一个简单的浏览器信息检测功能,要求:
检测浏览器的基本信息
显示当前页面的URL信息
使用对话框显示检测结果
function detectBrowserInfo () {
// 获取浏览器信息
let browserInfo = {
userAgent: navigator.userAgent,
platform: navigator.platform,
language: navigator.language,
onLine: navigator.onLine
};
// 获取页面URL信息
let urlInfo = {
href: window.location.href,
host: window.location.host,
pathname: window.location.pathname,
search: window.location.search
};
// 显示信息
console. log ( "浏览器信息:" , browserInfo);
// 每秒更新一次计时器
let timerInterval = setInterval (updateTimer, 1000 );
// 10秒后停止计时器
setTimeout ( function () {
clearInterval (timerInterval);
console. log ( "计时器已停止" );
}, 10000 );
}`
);
// 更新页面显示
let clockElement = document. getElementById ( 'digital-clock' );
if (clockElement) {
clockElement.textContent = timeString;
}
}
// 立即显示一次时间
updateClock ();
// 然后每秒更新一次
return setInterval (updateClock, 1000 );
}
// 启动时钟
let clockTimer = createDigitalClock ();
(
"片段标识符:"
, location.hash);
}
analyzeCurrentURL ();
equalIndex
=
pair.
indexOf
(
'='
);
if (equalIndex !== - 1 ) {
let name = pair. substring ( 0 , equalIndex);
let value = pair. substring (equalIndex + 1 );
// 解码URL编码的字符
name = decodeURIComponent (name);
value = decodeURIComponent (value);
parameters[name] = value;
}
});
}
return parameters;
}
// 使用示例
let urlParams = parseURLParameters ();
console. log ( "URL参数:" , urlParams);
// 访问特定参数
if (urlParams.category) {
console. log ( "商品类别:" , urlParams.category);
}
if (urlParams.page) {
console. log ( "当前页码:" , urlParams.page);
}
(replaceHistory) {
// 使用replace避免在历史记录中留下当前页面
location. replace (url);
} else {
// 普通跳转,会在历史记录中保留当前页面
location. assign (url);
}
}
// 根据条件进行导航
function conditionalNavigation () {
// 检查浏览器是否支持某个功能
if ( typeof (XMLHttpRequest) === 'undefined' ) {
// 如果不支持Ajax,跳转到静态版本
smartNavigate ( "static-version.html" , true );
console. log ( "浏览器不支持Ajax,跳转到静态版本" );
} else {
console. log ( "浏览器支持现代功能,继续使用当前页面" );
}
}
conditionalNavigation ();
function
goForward
() {
history. forward ();
console. log ( "执行前进操作" );
}
// 跳转到历史记录中的特定位置
function goToSpecificPage ( steps ) {
history. go (steps);
console. log ( `跳转 ${ steps } 页` );
}
return {
goBack,
goForward,
goToSpecificPage
};
}
let historyController = navigateHistory ();
newView;
updatePageContent (newView);
console. log ( `切换到视图: ${ newView }` );
console. log ( `历史记录: [${ viewHistory . join ( ', ' ) }]` );
}
function updatePageContent ( viewName ) {
// 模拟更新页面内容
let content = {
'home' : '欢迎来到首页' ,
'products' : '产品列表页面' ,
'about' : '关于我们页面' ,
'contact' : '联系我们页面'
};
console. log ( `页面内容: ${ content [ viewName ] || '未知页面'}` );
}
function goBackInApp () {
if (viewHistory. length > 0 ) {
let previousView = viewHistory. pop ();
changeView (previousView, false );
console. log ( "应用内后退成功" );
} else {
console. log ( "已经是最初页面,无法后退" );
}
}
return {
changeView,
goBack: goBackInApp,
getCurrentView : () => currentView
};
}
// 使用历史管理器
let appHistory = createSPAHistoryManager ();
// 模拟用户在应用中的导航
appHistory. changeView ( 'products' );
appHistory. changeView ( 'about' );
appHistory. changeView ( 'contact' );
// 用户点击后退
appHistory. goBack ();
);
for ( let key in browserInfo) {
console. log ( `${ key }: ${ browserInfo [ key ] }` );
}
return browserInfo;
}
// 检测特定功能的支持情况
function checkBrowserCapabilities () {
let capabilities = {
// 检查是否支持地理位置API
geolocation: 'geolocation' in navigator,
// 检查是否启用了Cookie
cookiesEnabled: navigator.cookieEnabled,
// 检查是否支持Java
javaEnabled: navigator.javaEnabled ? navigator. javaEnabled () : false ,
// 检查是否支持触摸事件
touchSupport: 'ontouchstart' in window,
// 检查本地存储支持
localStorage: typeof (Storage) !== "undefined"
};
console. log ( " \n 浏览器功能支持情况:" );
for ( let feature in capabilities) {
console. log ( `${ feature }: ${ capabilities [ feature ] ? '支持' : '不支持'}` );
}
return capabilities;
}
let info = getBrowserInfo ();
let caps = checkBrowserCapabilities ();
screenInfo) {
console. log ( `${ key }: ${ screenInfo [ key ] }` );
}
// 判断设备类型
let deviceType = determineDeviceType (screenInfo);
console. log ( `设备类型: ${ deviceType }` );
return screenInfo;
}
function determineDeviceType ( screenInfo ) {
let maxDimension = Math. max (screenInfo.totalWidth, screenInfo.totalHeight);
if (maxDimension <= 768 ) {
return "手机" ;
} else if (maxDimension <= 1024 ) {
return "平板电脑" ;
} else if (maxDimension <= 1366 ) {
return "小型笔记本" ;
} else {
return "桌面电脑或大屏幕设备" ;
}
}
// 根据屏幕信息调整应用设置
function adaptToScreen () {
let screenInfo = getScreenInfo ();
if (screenInfo.availableWidth < 768 ) {
console. log ( "检测到小屏幕设备,启用移动端优化" );
// 在实际应用中,这里可以加载移动端特定的CSS或JavaScript
} else {
console. log ( "检测到大屏幕设备,使用桌面端布局" );
}
// 根据颜色深度调整显示效果
if (screenInfo.colorDepth < 24 ) {
console. log ( "检测到较低的颜色深度,将使用简化的视觉效果" );
}
}
adaptToScreen ();
log
(
"用户确认删除文件"
);
return true ;
} else {
console. log ( "用户取消删除操作" );
return false ;
}
}
// prompt:获取输入
function getUserInput () {
let userName = prompt ( "请输入您的姓名:" , "默认姓名" );
if (userName !== null && userName. trim () !== "" ) {
console. log ( `用户输入的姓名: ${ userName }` );
return userName;
} else {
console. log ( "用户取消输入或输入为空" );
return null ;
}
}
return {
showAlert,
getConfirmation,
getUserInput
};
}
// 实际应用示例:用户注册流程
function userRegistrationFlow () {
let dialogs = demonstrateBasicDialogs ();
// 显示欢迎信息
dialogs. showAlert ();
// 获取用户姓名
let userName = dialogs. getUserInput ();
if (userName) {
// 确认用户信息
let confirmed = dialogs. getConfirmation ();
if (confirmed) {
console. log ( `用户 ${ userName } 注册成功` );
} else {
console. log ( "用户取消注册" );
}
}
}
// 注意:在实际运行中这会显示真实的对话框
// userRegistrationFlow();
(
`错误行号: ${
lineNumber
}`
);
console. log ( `错误列号: ${ columnNumber }` );
if (error) {
console. log ( `错误对象: ${ error . toString () }` );
}
// 记录错误到日志系统
logErrorToServer ({
message,
source,
lineNumber,
columnNumber,
userAgent: navigator.userAgent,
timestamp: new Date (). toISOString ()
});
// 返回true表示错误已被处理,阻止浏览器显示默认错误信息
return true ;
};
console. log ( "全局错误处理器已设置" );
}
// 模拟错误日志系统
function logErrorToServer ( errorInfo ) {
console. log ( "正在将错误信息发送到服务器..." );
console. log ( "错误详情:" , errorInfo);
// 在实际应用中,这里会发送Ajax请求到服务器
// fetch('/api/log-error', {
// method: 'POST',
// headers: {'Content-Type': 'application/json'},
// body: JSON.stringify(errorInfo)
// });
}
// 智能错误处理系统
function createSmartErrorHandler () {
let errorCount = 0 ;
let maxErrors = 5 ;
let errorTypes = {};
window. onerror = function ( message , source , lineNumber , columnNumber , error ) {
errorCount ++ ;
// 统计错误类型
let errorType = message. split ( ':' )[ 0 ] || 'Unknown' ;
errorTypes[errorType] = (errorTypes[errorType] || 0 ) + 1 ;
console. log ( `错误 #${ errorCount }: ${ message }` );
// 如果错误过多,停止处理新错误
if (errorCount > maxErrors) {
console. log ( "错误数量过多,停止详细错误处理" );
return true ;
}
// 根据错误类型采取不同的处理策略
if (message. includes ( 'Network' )) {
console. log ( "检测到网络错误,建议用户检查网络连接" );
} else if (message. includes ( 'ReferenceError' )) {
console. log ( "检测到引用错误,可能是代码问题" );
}
// 每5个错误显示一次统计信息
if (errorCount % 5 === 0 ) {
console. log ( "错误统计:" , errorTypes);
}
return true ;
};
}
// 测试错误处理
function testErrorHandling () {
setupGlobalErrorHandler ();
// 模拟一些错误(注意:这些会被错误处理器捕获)
try {
// 故意引发错误来测试处理器
throw new Error ( "这是一个测试错误" );
} catch (e) {
console. log ( "捕获到预期的测试错误:" , e.message);
}
// 模拟异步错误
setTimeout ( function () {
try {
// 这个错误会被全局处理器捕获
undefinedFunction ();
} catch (e) {
console. log ( "异步错误被捕获" );
}
}, 100 );
}
testErrorHandling ();
console. log ( "mainContent元素不存在或id冲突" );
}
// 但是,如果id与Window的现有属性冲突,自动变量不会被创建
// 比如,id="location"的元素不会创建全局变量
}
// 更安全的元素访问方法
function safeElementAccess () {
// 推荐使用getElementById方法
let contentElement = document. getElementById ( 'mainContent' );
if (contentElement) {
console. log ( "安全地找到元素:" , contentElement.tagName);
return contentElement;
} else {
console. log ( "未找到指定元素" );
return null ;
}
}
// 创建元素访问工具
function createElementAccessHelper () {
// 简化的元素选择器
function $ ( id ) {
return document. getElementById (id);
}
// 批量元素访问
function getElements ( ids ) {
let elements = {};
ids. forEach ( function ( id ) {
let element = document. getElementById (id);
if (element) {
elements[id] = element;
console. log ( `找到元素: ${ id }` );
} else {
console. log ( `未找到元素: ${ id }` );
}
});
return elements;
}
// 元素存在性检查
function checkElements ( ids ) {
let results = {};
ids. forEach ( function ( id ) {
results[id] = document. getElementById (id) !== null ;
});
console. log ( "元素存在性检查结果:" , results);
return results;
}
return {
$,
getElements,
checkElements
};
}
// 使用示例
let elementHelper = createElementAccessHelper ();
// 检查页面中的关键元素
let keyElements = [ 'header' , 'navigation' , 'mainContent' , 'footer' ];
elementHelper. checkElements (keyElements);
// 批量获取元素
let pageElements = elementHelper. getElements ([ 'mainContent' , 'sidebar' ]);
openTime:
new
Date
()
});
console. log ( `成功打开窗口: ${ name }` );
// 监听窗口关闭事件
let checkClosed = setInterval ( function () {
if (newWindow.closed) {
console. log ( `窗口 ${ name } 已被关闭` );
clearInterval (checkClosed);
removeFromOpenWindows (newWindow);
}
}, 1000 );
return newWindow;
} else {
console. log ( "窗口打开失败,可能被弹窗阻止器阻止" );
return null ;
}
} catch (error) {
console. log ( "打开窗口时发生错误:" , error.message);
return null ;
}
}
// 从打开窗口列表中移除
function removeFromOpenWindows ( windowObj ) {
openWindows = openWindows. filter ( item => item.window !== windowObj);
}
// 关闭指定窗口
function closeWindow ( windowObj ) {
if (windowObj && ! windowObj.closed) {
windowObj. close ();
console. log ( "窗口已关闭" );
}
}
// 关闭所有打开的窗口
function closeAllWindows () {
openWindows. forEach ( function ( windowInfo ) {
if ( ! windowInfo.window.closed) {
windowInfo.window. close ();
console. log ( `关闭窗口: ${ windowInfo . name }` );
}
});
openWindows = [];
}
// 获取打开窗口的信息
function getOpenWindowsInfo () {
let activeWindows = openWindows. filter ( info => ! info.window.closed);
console. log ( `当前打开的窗口数量: ${ activeWindows . length }` );
activeWindows. forEach ( function ( info , index ) {
console. log ( `窗口 ${ index + 1 }: ${ info . name } - ${ info . url }` );
});
return activeWindows;
}
return {
openNewWindow,
closeWindow,
closeAllWindows,
getOpenWindowsInfo
};
}
// 实际应用示例
function demonstrateWindowManagement () {
let windowManager = createWindowManager ();
// 打开帮助窗口
function openHelpWindow () {
return windowManager. openNewWindow (
'help.html' ,
'helpWindow' ,
'width=600,height=400,scrollbars=yes,resizable=yes'
);
}
// 打开设置窗口
function openSettingsWindow () {
return windowManager. openNewWindow (
'settings.html' ,
'settingsWindow' ,
'width=500,height=600,scrollbars=no,resizable=no'
);
}
// 打开无装饰的弹出窗口
function openPopupWindow () {
return windowManager. openNewWindow (
'popup.html' ,
'popupWindow' ,
'width=300,height=200,toolbar=no,menubar=no,location=no,status=no'
);
}
return {
openHelpWindow,
openSettingsWindow,
openPopupWindow,
manager: windowManager
};
}
let windowDemo = demonstrateWindowManagement ();
iframe.style.border = '1px solid #ccc' ;
// 添加加载事件监听
iframe. onload = function () {
console. log ( `iframe ${ id } 加载完成` );
console. log ( `iframe URL: ${ this . src }` );
};
iframe. onerror = function () {
console. log ( `iframe ${ id } 加载失败` );
};
return iframe;
}
// 获取iframe的Window对象
function getIframeWindow ( iframeId ) {
let iframe = document. getElementById (iframeId);
if (iframe && iframe.contentWindow) {
console. log ( `获取到iframe ${ iframeId } 的Window对象` );
return iframe.contentWindow;
} else {
console. log ( `无法获取iframe ${ iframeId } 的Window对象` );
return null ;
}
}
// 向iframe发送消息
function postMessageToIframe ( iframeId , message , targetOrigin = '*' ) {
let iframeWindow = getIframeWindow (iframeId);
if (iframeWindow) {
iframeWindow. postMessage (message, targetOrigin);
console. log ( `向iframe ${ iframeId } 发送消息:` , message);
}
}
// 监听来自iframe的消息
function listenToIframeMessages () {
window. addEventListener ( 'message' , function ( event ) {
console. log ( '收到iframe消息:' );
console. log ( '来源:' , event.origin);
console. log ( '数据:' , event.data);
// 验证消息来源的安全性
if (event.origin === 'https://trusted-domain.com' ) {
console. log ( '消息来源可信,处理消息' );
handleTrustedMessage (event.data);
} else {
console. log ( '消息来源不可信,忽略消息' );
}
});
console. log ( '开始监听iframe消息' );
}
function handleTrustedMessage ( data ) {
if (data.type === 'resize' ) {
console. log ( `iframe请求调整大小: ${ data . width }x${ data . height }` );
} else if (data.type === 'navigate' ) {
console. log ( `iframe请求导航到: ${ data . url }` );
}
}
return {
createIframe,
getIframeWindow,
postMessageToIframe,
listenToIframeMessages
};
}
// 演示iframe框架间通信
function demonstrateIframeCommunication () {
let iframeManager = createIframeManager ();
// 设置消息监听
iframeManager. listenToIframeMessages ();
// 创建并添加iframe到页面
function setupIframes () {
let container = document. getElementById ( 'iframe-container' ) || document.body;
// 创建内容iframe
let contentIframe = iframeManager. createIframe (
'content.html' ,
'contentFrame' ,
'600px' ,
'400px'
);
container. appendChild (contentIframe);
// 等待iframe加载完成后发送初始化消息
setTimeout ( function () {
iframeManager. postMessageToIframe ( 'contentFrame' , {
type: 'init' ,
config: {
theme: 'light' ,
language: 'zh-CN'
}
});
}, 1000 );
}
// 模拟iframe之间的数据交换
function simulateIframeInteraction () {
// 发送配置更新
iframeManager. postMessageToIframe ( 'contentFrame' , {
type: 'updateConfig' ,
data: {
showToolbar: true ,
enableSearch: true
}
});
// 发送数据
iframeManager. postMessageToIframe ( 'contentFrame' , {
type: 'data' ,
payload: [
{ id: 1 , name: '项目A' , status: '进行中' },
{ id: 2 , name: '项目B' , status: '已完成' }
]
});
}
return {
setupIframes,
simulateIframeInteraction
};
}
let iframeDemo = demonstrateIframeCommunication ();
"定时器执行次数:"
+
count);
// 执行5次后清除定时器
if (count >= 5 ) {
clearInterval (timer2);
console. log ( "定时器已清除" );
}
}, 2000 );
// 如果需要提前取消定时器
// clearTimeout(timer1); // 取消延迟执行的定时器
// clearInterval(timer2); // 取消重复执行的定时器
function navigateToPage2 ( url ) {
window.location. assign (url);
}
// 方法3:使用replace()方法(不会在历史记录中留下记录)
function navigateToPage3 ( url ) {
window.location. replace (url);
}
// 使用示例
// navigateToPage1("https://www.example.com");
// navigateToPage2("https://www.example.com");
// navigateToPage3("https://www.example.com");
console. log ( "URL信息:" , urlInfo);
// 使用alert显示(简单示例)
let message = "用户代理:" + browserInfo.userAgent + " \n " ;
message += "平台:" + browserInfo.platform + " \n " ;
message += "语言:" + browserInfo.language + " \n " ;
message += "在线状态:" + (browserInfo.onLine ? "在线" : "离线" );
alert (message);
return {
browser: browserInfo,
url: urlInfo
};
}
// 调用函数
// detectBrowserInfo();