JavaScript学习教程,从入门到精通,JavaScript BOM (Browser Object Model) 详解(18)

news2025/4/19 5:04:39

JavaScript BOM (Browser Object Model) 详解

1. BOM 介绍

BOM (Browser Object Model) 是浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象。BOM的核心对象是window,它表示浏览器的一个实例。

BOM包含的主要对象:

  • window:浏览器窗口
  • navigator:浏览器信息
  • screen:显示器信息
  • history:浏览器历史记录
  • location:URL信息

2. window 对象

window对象是BOM的核心,所有全局JavaScript对象、函数和变量自动成为window对象的成员。

全局变量和函数

var globalVar = "我是全局变量"; // 等同于 window.globalVar

function globalFunc() {
    console.log("我是全局函数");
}
// 等同于 window.globalFunc()

3. 全局作用域

在全局作用域中声明的变量和函数都会成为window对象的属性和方法。

// 示例:全局作用域
var a = 10;
console.log(window.a); // 10

function test() {
    console.log("测试函数");
}
window.test(); // "测试函数"

4. 系统对话框

浏览器提供了三种系统对话框:

  • alert()
  • confirm()
  • prompt()

alert() 示例

// 显示警告框
window.alert("这是一个警告信息"); // 简写为 alert("这是一个警告信息")

confirm() 示例

// 显示确认框,返回布尔值
let isConfirmed = confirm("你确定要删除吗?");
if (isConfirmed) {
    console.log("用户点击了确定");
} else {
    console.log("用户点击了取消");
}

prompt() 示例

// 显示提示框,返回用户输入的字符串
let userName = prompt("请输入你的名字", "默认名字");
if (userName !== null) {
    console.log(`你好, ${userName}`);
} else {
    console.log("用户取消了输入");
}

5. 打开和关闭窗口

window.open() 方法

// 打开新窗口
let newWindow = window.open(
    "https://www.example.com", // URL
    "exampleWindow",          // 窗口名称
    "width=400,height=300"    // 窗口特性
);

// 检查窗口是否被阻止
if (newWindow === null) {
    alert("弹出窗口被浏览器阻止了!");
}

window.close() 方法

// 关闭当前窗口
function closeCurrentWindow() {
    if (confirm("确定要关闭窗口吗?")) {
        window.close();
    }
}

// 关闭之前打开的窗口
if (newWindow && !newWindow.closed) {
    newWindow.close();
}

6. 窗口位置

获取窗口位置

// 跨浏览器获取窗口位置
let windowLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
let windowTop = window.screenTop !== undefined ? window.screenTop : window.screenY;

console.log(`窗口位置 - 左: ${windowLeft}, 上: ${windowTop}`);

移动窗口位置

// 移动窗口到指定位置
function moveWindowTo(x, y) {
    window.moveTo(x, y); // 绝对位置
    // window.moveBy(dx, dy); // 相对当前位置移动
}

// 使用示例
moveWindowTo(100, 200);

7. 窗口大小

获取窗口大小

// 跨浏览器获取视口大小
let viewportWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
let viewportHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

console.log(`视口大小 - 宽: ${viewportWidth}, 高: ${viewportHeight}`);

// 获取屏幕大小
console.log(`屏幕大小 - 宽: ${screen.width}, 高: ${screen.height}`);

调整窗口大小

// 调整窗口大小
function resizeWindow(width, height) {
    window.resizeTo(width, height); // 绝对大小
    // window.resizeBy(dWidth, dHeight); // 相对当前大小调整
}

// 使用示例
resizeWindow(500, 400);

8. 框架操作

访问框架

<!-- HTML框架示例 -->
<frameset cols="25%,50%,25%">
    <frame name="leftFrame" src="left.html">
    <frame name="mainFrame" src="main.html">
    <frame name="rightFrame" src="right.html">
</frameset>
// 访问框架
let leftFrame = window.frames["leftFrame"]; // 或 window.leftFrame

// 在框架中访问父窗口
if (window.parent !== window) {
    // 当前窗口是框架
    console.log("当前窗口是框架");
}

// 访问顶层窗口
let topWindow = window.top;

iframe 操作

<!-- iframe示例 -->
<iframe id="myIframe" src="https://www.example.com" width="600" height="400"></iframe>
// 获取iframe元素
let iframe = document.getElementById("myIframe");

// 访问iframe内容
iframe.onload = function() {
    try {
        let iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
        console.log("iframe加载完成", iframeDoc.title);
    } catch (e) {
        console.log("跨域访问被拒绝");
    }
};

// 改变iframe src
function changeIframeSrc(url) {
    iframe.src = url;
}

9. 示例:第三方跳转

/**
 * 第三方跳转函数
 * @param {string} url - 要跳转的URL
 * @param {string} [target="_blank"] - 打开方式 (_blank, _self, _parent, _top)
 * @param {Object} [features] - 窗口特性 (width, height等)
 */
function redirectToThirdParty(url, target = "_blank", features = null) {
    // 安全检查 - 验证URL
    if (!url || typeof url !== "string") {
        console.error("无效的URL");
        return;
    }
    
    // 简单的URL格式验证
    try {
        new URL(url); // 如果URL无效会抛出错误
    } catch (e) {
        console.error("URL格式不正确:", e.message);
        return;
    }
    
    // 如果是新窗口且有特性参数
    if (target === "_blank" && features) {
        let featuresStr = Object.entries(features)
            .map(([key, value]) => `${key}=${value}`)
            .join(",");
        
        window.open(url, target, featuresStr);
    } else {
        // 普通跳转
        window.location.href = url;
    }
    
    // 记录跳转
    console.log(`跳转到第三方网站: ${url}`);
}

// 使用示例1: 简单跳转
redirectToThirdParty("https://www.google.com");

// 使用示例2: 在新窗口中打开并指定大小
redirectToThirdParty(
    "https://www.baidu.com",
    "_blank",
    { width: 800, height: 600 }
);

// 使用示例3: 在当前窗口打开
redirectToThirdParty("https://github.com", "_self");

防止跳转劫持的安全措施

// 安全跳转函数 - 防止跳转劫持
function safeRedirect(url, delay = 0) {
    // 显示用户控制界面
    const redirectInfo = document.createElement("div");
    redirectInfo.style.position = "fixed";
    redirectInfo.style.top = "0";
    redirectInfo.style.left = "0";
    redirectInfo.style.width = "100%";
    redirectInfo.style.backgroundColor = "#ffeb3b";
    redirectInfo.style.padding = "10px";
    redirectInfo.style.textAlign = "center";
    redirectInfo.style.zIndex = "1000";
    redirectInfo.style.boxShadow = "0 2px 5px rgba(0,0,0,0.2)";
    
    redirectInfo.innerHTML = `
        <p>即将跳转到: ${url}</p>
        <button id="continueRedirect">继续跳转</button>
        <button id="cancelRedirect">取消跳转</button>
        <span id="countdown">${delay}</span>秒后自动跳转
    `;
    
    document.body.appendChild(redirectInfo);
    
    // 倒计时功能
    let remaining = delay;
    const countdownElement = document.getElementById("countdown");
    const countdownInterval = setInterval(() => {
        remaining--;
        countdownElement.textContent = remaining;
        
        if (remaining <= 0) {
            clearInterval(countdownInterval);
            performRedirect();
        }
    }, 1000);
    
    // 按钮事件
    document.getElementById("continueRedirect").addEventListener("click", () => {
        clearInterval(countdownInterval);
        performRedirect();
    });
    
    document.getElementById("cancelRedirect").addEventListener("click", () => {
        clearInterval(countdownInterval);
        document.body.removeChild(redirectInfo);
    });
    
    function performRedirect() {
        document.body.removeChild(redirectInfo);
        window.location.href = url;
    }
}

// 使用示例
safeRedirect("https://www.example.com", 5);

以上代码提供了BOM相关功能的全面实现,包括窗口操作、对话框、框架操作等,并且包含了详细的注释和安全措施。

以下是基于BOM(浏览器对象模型)的具体开发案例,结合了窗口操作、对话框、定时器等核心功能,并附有详细代码注释:


一、窗口操作案例

1. 新窗口创建与内容注入
// 创建新窗口并写入内容
const newWindow = window.open('', 'demoWindow', 'width=600,height=400');
if (newWindow) {
  newWindow.document.write('<h1>新窗口内容</h1><p>通过BOM动态生成</p>');
  // 5秒后自动关闭窗口
  setTimeout(() => newWindow.close(), 5000);
} else {
  alert('弹出窗口被浏览器阻止!');
}

功能:通过window.open()创建新窗口并注入HTML内容,5秒后自动关闭。

2. 窗口居中显示
function openCenteredWindow(url, width, height) {
  const left = (screen.width - width) / 2;
  const top = (screen.height - height) / 2;
  window.open(url, '', `width=${width},height=${height},left=${left},top=${top}`);
}

功能:计算屏幕居中坐标,打开指定大小的窗口。


二、对话框与用户交互

1. 表单提交确认
document.querySelector('form').addEventListener('submit', (e) => {
  const isConfirmed = confirm('确认提交数据吗?');
  if (!isConfirmed) e.preventDefault(); // 取消提交
});

功能:提交前弹出确认框,避免误操作。

2. 输入验证提示
const age = prompt('请输入您的年龄', '18');
if (age >= 18) {
  alert('欢迎访问成人内容!');
} else {
  window.location.href = 'https://child-safe-site.com';
}

功能:通过prompt获取用户输入并跳转不同页面。


三、定时器与动态效果

1. 倒计时跳转页面
let countdown = 10;
const timer = setInterval(() => {
  document.getElementById('countdown').textContent = `${countdown}s后跳转`;
  if (countdown-- <= 0) {
    clearInterval(timer);
    window.location.href = 'https://example.com';
  }
}, 1000);

功能:显示倒计时并自动跳转,常用于广告页或登录后重定向。

2. 防抖窗口 resize 事件
let resizeTimer;
window.addEventListener('resize', () => {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(() => {
    console.log('窗口稳定大小:', window.innerWidth, window.innerHeight);
  }, 200);
});

功能:避免频繁触发resize事件,优化性能。


四、框架与跨窗口通信

1. 父窗口与iframe交互
<iframe id="myFrame" src="child.html"></iframe>
<script>
  const frame = document.getElementById('myFrame');
  frame.onload = () => {
    // 向iframe发送消息
    frame.contentWindow.postMessage('Hello from parent!', '*');
  };
  // 接收子窗口消息
  window.addEventListener('message', (e) => {
    if (e.origin === 'https://trusted-domain.com') {
      console.log('子窗口消息:', e.data);
    }
  });
</script>

功能:使用postMessage实现跨域安全通信。


五、实战案例:拖拽模态框

// 获取模态框元素
const modal = document.querySelector('.modal');
const header = modal.querySelector('.modal-header');
let isDragging = false;
let offsetX, offsetY;

header.addEventListener('mousedown', (e) => {
  isDragging = true;
  offsetX = e.clientX - modal.offsetLeft;
  offsetY = e.clientY - modal.offsetTop;
});

document.addEventListener('mousemove', (e) => {
  if (!isDragging) return;
  modal.style.left = `${e.clientX - offsetX}px`;
  modal.style.top = `${e.clientY - offsetY}px`;
});

document.addEventListener('mouseup', () => isDragging = false);

功能:通过计算鼠标偏移量实现模态框拖拽。


六、安全跳转案例

function safeRedirect(url) {
  if (url.startsWith('https://trusted.com')) {
    window.location.href = url;
  } else {
    console.error('拒绝跳转到非信任域名!');
  }
}

功能:防止恶意重定向攻击。


以上案例覆盖了BOM的核心应用场景,可根据实际需求调整参数或扩展功能。更多高级用法(如结合Electron开发桌面应用)可参考Electron官方文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2337717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

42.[前端开发-JavaScript高级]Day07-手写apply-call-bind-块级作用域

手写apply-call-bind <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevi…

Vscode 插件开发

文章目录 1、使用vscode官方插件生成框架&#xff0c;下载脚手架2、使用脚手架初始化项目&#xff0c;这里我选择的是js3、生成的文件结构如下&#xff0c;重要的就是以下两个文件4、代码5、打包使用6、发布官网地址7、publisher ID undefined provided in the extension manif…

RTT添加一个RTC时钟驱动,以DS1307为例

添加一个外部时钟芯片 这里多了一个选项 复制drv_rtc.c,重命名为drv_rtc_ds1307.c 添加到工程中 /*** @file drv_rtc_ds1307.c* @brief * @author jiache (wanghuan3037@fiberhome.com)* @version 1.0* @date 2025-01-08* * @copyright Copyright (c) 2025 58* */ #

常见的低代码策略整理

低代码策略通过简化开发流程、降低技术门槛、提升效率&#xff0c;帮助用户快速构建灵活可靠的应用。这些策略的核心优势体现在以下方面&#xff1a; 快速交付与降本增效 减少编码需求&#xff1a;通过可视化配置&#xff08;如变量替换、表达式函数&#xff09;替代传统编码…

从彩色打印单行标准九九表学习〖代码情书〗的书写范式(Python/DeepSeek)

写给python终端的情书&#xff0c;学习代码设计/书写秘笈。 笔记模板由python脚本于2025-04-17 12:49:08创建&#xff0c;本篇笔记适合有python编程基础的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简…

QML与C++:基于ListView调用外部模型进行增删改查(附自定义组件)

目录 引言相关阅读项目结构文件组织 核心技术实现1. 数据模型设计联系人项目类 (datamodel.h)数据模型类 (datamodel.h)数据模型实现 (datamodel.cpp) 2. 主程序入口点 (main.cpp)3. 主界面设计 (Main.qml)4. 联系人对话框 (ContactDialog.qml)5. 自定义组件CustomTextField.qm…

postman莫名奇妙报错,可能是注释引起的。postman 过滤请求体中的注释。

postman莫名奇妙报错&#xff0c;可能是注释引起的。postman 过滤请求体中的注释。 1、问题描述2、问题分析3、解决方法 1、问题描述 postman http请求测试时&#xff0c;如果在请求体中添加了注释&#xff0c;那么这个注释会被带到服务端执行&#xff0c;导致服务端接口返回报…

扩增子分析|基于R语言microeco包进行微生物群落网络分析(network网络、Zi-Pi关键物种和subnet子网络图)

一、引言 microeco包是福建农林大学姚敏杰教授团队开发的扩增子测序集成分析。该包综合了扩增子测序下游分析的多种功能包括群落组成、多样性、网络分析、零模型等等。通过简单的几行代码可实现复杂的分析。因此&#xff0c;microeco包发表以来被学界广泛关注&#xff0c;截止2…

中间件--ClickHouse-4--向量化执行(什么是向量?为什么向量化执行的更快?)

1、向量&#xff08;Vector&#xff09;的概念 &#xff08;1&#xff09;、向量的定义 向量&#xff1a;在计算机科学中&#xff0c;向量是一组同类型数据的有序集合&#xff0c;例如一个包含多个数值的数组。在数据库中&#xff0c;向量通常指批量数据&#xff08;如一列数…

【SpringBoot+Vue自学笔记】001

跟着这位老师学习的&#xff1a;https://www.bilibili.com/video/BV1nV4y1s7ZN?vd_sourceaf46ae3e8740f44ad87ced5536fc1a45 前后端开发技术的全栈课程&#xff1a; Java EE企业级框架&#xff1a;SpringBootMyBatisPlus Web前端核心框架&#xff1a;VueElement UI 公共云…

第十节:性能优化-如何排查组件不必要的重复渲染?

工具&#xff1a;React DevTools Profiler 方法&#xff1a;memo、shouldComponentUpdate深度对比 React 组件性能优化&#xff1a;排查与解决重复渲染问题指南 一、定位性能问题&#xff1a;React DevTools 高级用法 使用 React Developer Tools Profiler 精准定位问题组件&…

MATLAB项目实战(一)

题目&#xff1a; 某公司有6个建筑工地要开工&#xff0c;每个工地的位置&#xff08;用平面坐标系a&#xff0c;b表示&#xff0c;距离单位&#xff1a;km&#xff09;及水泥日用量d(t)由下表给出&#xff0e;目前有两个临时料场位于A(5,1)&#xff0c;B(2,7)&#xff0c;日储…

spring boot 文件下载

1.添加文件下载工具依赖 Commons IO is a library of utilities to assist with developing IO functionality. <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version> </depe…

微服务链路追踪:SleuthZipkin

文章目录 Sleuth & Zipkin一、Sleuth\&Zipkin介绍二、搭建环境三、Sleuth入门操作四、Zipkin搭建及操作五、RabbitMQ方式发送信息六、Elasticsearch持久化 SpringBootAdmin一、Actuator介绍二、Actuator快速入门三、SpringBootAdmin介绍四、SpringBootAdmin快速入门4.1…

java面试篇 4.9(mybatis+微服务+线程安全+线程池)

目录 mybatis&#xff1a; 1、mybatis的执行流程 2、mybatis是否支持延迟加载&#xff1f; 当我们需要去开启全局的懒加载时&#xff1a; 3、mybatis的一级和二级缓存 微服务 1、springcloud五大组件有哪些 2、服务注册和发现是什么意思&#xff1f;springcloud如何实现…

基于电子等排体的3D分子生成模型 ShEPhERD - 评测

一、背景介绍 ShEPhERD 是一个由 MIT 开发的一个 3D 相互作用感知的 ligand-based的分子生成模型&#xff0c;以 arXiv 预印本的形式发表于 2024 年&#xff0c;被ICLR2025 会议接收。文章链接&#xff1a;https://openreview.net/pdf?idKSLkFYHlYg ShEPhERD 是一种基于去噪扩…

GR00T N1:面向通用类人机器人的开放基础模型

摘要 通用型机器人需要具备多功能的身体和智能的大脑。近年来&#xff0c;类人机器人的发展在构建人类世界中的通用自主性硬件平台方面展现出巨大潜力。一个经过大量多样化数据源训练的机器人基础模型&#xff0c;对于使机器人能够推理新情况、稳健处理现实世界的多变性以及快…

QT简单实例

QT简单实例 QT简单实例一&#xff1a;通过拖动创建1.创建工程2.拖动控件实现响应3.文件目录3.1 TestQDialog.pro3.2 main.cpp3.3 dialog.h3.4 dialog.cpp 二&#xff1a;通过动态创建1.创建工程2.文件目录2.1 TestQDialogSelf.pro2.2 main.cpp2.3 dialog.h2.4 dialog.cpp QT简单…

Linux:初学者的简单指令

文章目录 pwd&#xff08;Print working directory&#xff09;whoamilsmkdir ~~cd ~~touch ~~rm ~~ 充当后端服务,我们用xshell工具来进行操作 其中Linux文件是/目录/目录/目录或文件/来表示的&#xff08;其中目录可以看作是windows操作系统的文件夹&#xff0c;只是Linux中…

端侧大模型综述On-Device Language Models: A Comprehensive Review

此为机器翻译&#xff0c;仅做个人学习使用 设备端语言模型&#xff1a;全面回顾 DOI&#xff1a;10.48550/arXiv.2409.00088 1 摘要 大型语言模型 &#xff08;LLM&#xff09; 的出现彻底改变了自然语言处理应用程序&#xff0c;由于减少延迟、数据本地化和个性化用户体验…