BOM你真的了解吗?

前言
我们常常会认为JS是由ES和Web APIS组成的,而Web APIS由是由BOM和DOM组成的
那到底什么才是BOM呢?

BOM的概念

  • BOM(Browser Object Model) 是指浏览器对象模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。BOM由多个对象组成,其中代表浏览器窗口的window对象是BOM的顶层对象,其他对象都是该对象的子对象
  • 我们在浏览器中的一些操作都可以使用BOM的方式进行编程处理,比如:刷新浏览器、后退、前进、在浏览器中输入URL等。
window 对象
  • window 是浏览器的顶级对象,当调用 window 下的属性和方法时,可以省略 window
  • 注意:window下两个特殊的属性 window.name、window.top

对话框

  • confirm
    • 方法有返回值,根据按钮点击情况来返回true或false

onload事件

  • 我们可以给 window 对象或者 img 等元素添加 onload 加载事件,表示只有绑定事件的元素加载完毕才能触发事件,才能执行事件函数。
  • 其中 window 对象加载完毕:指的是所有HTML结构加载完,并且外部引入资源(js、css、img、视频)也加载完毕
应用
  • 利用 window.onload事件,可以将js代码提前到html结构之前。
  • 注意:一个页面中只能有一个 window.onload 事件

延时器

  • 延时器是 window 对象的一个方法,类似于定时炸弹
  • 语法:window.setTimeout(func, time);
  • 第一个参数:演示执行的函数,可以是匿名函数定义,或者是一个函数名的引用,注意不要加()
  • 第二个参数:延时的时间,以毫秒计数,1000毫秒等于1秒
  • 功能:在指定的时间后,延迟执行一个函数
清除延时器
  • window 对象的一个方法
  • 语法:window.clearTimeout(timeout);
  • 参数:指定的演示器变量名引用
  • 功能:清除指定的延时器
  • 注意:清除的延时器需要存储到一个变量中,便于后期清除调用

函数节流操作

var btn = document.getElementById("btn");
var lock = false;

btn.onclick = function () {
    if (lock) {
        return;
    }

    console.log(Math.random());

    lock = true;

    setTimeout(function () {
        lock = false;
    }, 2000)
};

定时器

  • 定时器是window对象的一个方法,相当于定时闹钟,每个固定的时间响一次
  • 语法:window.setInterval(func, interval);
  • 第一个参数:每次执行的函数,可以使匿名函数定义,或者是一个函数名的引用,注意不要加()。
  • 第二个参数:时间间隔,以毫秒计数,1000毫秒等于1秒
  • 功能:每隔一个指定的时间,周期性的执行一个函数
清除定时器
  • window 对象的一个方法
  • 语法:window.clearInterval(timer)
  • 参数:指定的定时器变量名引用
  • 功能:清除指定的定时器
  • 注意:清除的定时器需要存储到一个变量中,便于后期清除调用

简单运动

  • 是一种视觉暂留效果,只要元素变化过程时间够短,给人眼造成的效果就是一个运动的效果,人眼的视觉残留的时间0.1-0.4秒之间
  • 制作方法:通过定时器,实现每隔一个极短的时间(50-100毫秒左右)执行函数,函数内部让运动的属性值发生变化
提高运动速度的方法
  • 缩短时间间隔,增加了每秒移动的次数
  • 加大步长,让每一次走的步长增加

清除定时器的问题

  • 将定时器的开始和停止过程书写在不同的时间函数内部,容易出现用户错误点击情况
    • 多次点击开始,会造成加速
    • 多次点击开始,不能够在停止

设表先关方法

  • 每次开启新定时器之前,都清除一次前面的定时器

拉钟停表

  • 需求:要求元素走到指定位置停止,例如让元素停止在500px的位置
  • 问题:如果步长设置的不合理,停止的位置可能不是正好在500处
  • 解决方法:在定时器内部每次都要判断是否走到了终点,要不要停止定时器;如果走到了终点,强行拉到终点,并停止定时器

步标整除

  • 需求:在规定时间内让元素走到规定的结束位置,时间间隔可以更改
  • 例如:让元素在2秒钟内,left属性从 0 走到 500px
  • 解决方法:
    • 总距离 == 步长 * 次数
    • 时间间隔自定义,总时长固定
    • 求出总次数 = 总时间 / 时间间隔
    • 定义计数器变量,每执行一次定时器函数增加计数1,直到执行达到总次数,停止定时器
    // 获取元素
    var start = document.getElementById("start");
    var box = document.getElementById("box");
    
    // 已知 开始位置、结束位置、总时长、时间间隔
    // 总距离 = 步长 * 总次数
    // 总距离 = 结束位置 - 起始位置  ,已知可以求出来
    // 总次数 = 总时长 / 时间间隔 ,已知可以求出来
    // 步长 = (结束位置 - 起始位置) / (总时长 / 时间间隔)

    // 信号量 ,也相当于初始值
    var nowLeft = 200;
    // 结束位置
    var endLeft = 500;
    // 总时长
    var time = 1000;
    // 时间间隔
    var interval = 50;
    // 运算总次数
    var maxcount = time / interval;
    // 运算出每一次的步长
    var step = (endLeft - nowLeft) / maxcount;
    // 定义一个次数的累加器
    var count = 0;

    // 准备条件结束可以开始定时器了
    var timer;
    start.onclick = function () {
      timer = setInterval(function () {
        // 让元素的属性每一次变化一个步长
        nowLeft += step;
        // 每运动一次让次数累加器加 1
        count++;
        // 停止定时器
        if (count >= maxcount) {
          // 拉终停表
          nowLeft = endLeft;
          clearInterval(timer);
        }
        // 给属性赋值
        box.style.left = nowLeft + "px";
      },interval);
    };

封装动画函数

        but.onclick = function () {
            animate(box, {
                left: 400,
                width: 300,
                height: 200,
                opacity: 1
            }, 2000);
        }

        function animate(ele, end, time) {
            // 起始位置的对象,需要先定义一个空对象
            var now = {};
            // end 对象遍历,获取属性名
            for (var k in end) {
                now[k] = parseFloat(window.getComputedStyle(ele)[k]);
            }
            // 自定义时间间隔
            var interval = 50;
            // 计算总次数
            var maxCount = time / interval;
            // 次数累加器
            var count = 0;
            // 对象中的每个属性都有自己的步长,也可以放到一个步长对象中
            var step = {};
            // 遍历结束对象,计算每个属性的步长
            for (var k in end) {
                step[k] = (end[k] - now[k]) / maxCount
            }
            // 定时器
            var timer;
            timer = setInterval(function () {
                // 每个属性发生变化,赋值给now对象中的每一项
                for (var k in end) {
                    now[k] += step[k];
                };
                // 累计运动次数
                count++;
                // 判断定时器是否结束
                if (count >= maxCount) {
                    // 拉终停表
                    for (var k in end) {
                        now[k] = end[k];
                    };
                    clearInterval(timer);
                }
                // 赋值给对应元素对象属性
                for (var k in now) {
                    if (k === 'opacity') {
                        ele.style[k] = now[k]
                    } else {
                        ele.style[k] = now[k] + "px"
                    }
                };
            }, interval)
        }

location对象

  • location 对象是 window 对象下的一个属性,使用的时候可以省略 window 对象
  • location 可以获取或者设置浏览器地址栏的 URL

URL了解

  • 统一资源定位符(Uniform Resource Locator, URL)
  • URL的组成:scheme://host:port/path?query#fragment
    • 例如:http://www.lagou.com:80/a/b/index/html?name=zs&age=18#bottom
  • scheme:通信协议,常用的hhtp, ftp, maito等
  • host:主机,服务器(计算机)域名系统(DNS)主机名或 IP 地址
  • port:端口号,整数,可选,省略时使用方案的默认端口,如http的默认端口为80
  • path:路径,由零或多个"/"符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
  • query:查询,可选,用于动态网页传递参数,可有多个参数,用"&“符号隔开,每个参数的名和值用”="符号隔开。例如:name=zs
  • fragment:信息披阿奴单,字符串,锚点

history 对象

  • history 对象是 window 对象下的一个属性,使用的时候可以省略 window 对象
  • history 对象可以与浏览器历史记录进行交互,浏览器历史记录是对用户所访问的页面按时间顺序进行的记录和保存
  • back()
  • forward()
  • go()
<think>好的,用户现在问的是“文件头BoM是什么样的?”,我需要详细解释BOM的概念、作用以及在同编码中的表现。首先,我应该确认用户可能对BOM了解的程度,可能是一个开发者或者处理文本文件的普通用户。 BOM是字节顺序标记,用于标识文本文件的编码方式和字节顺序。常见于UTF编码,特别是UTF-8、UTF-16和UTF-32。用户可能遇到了文件乱码的问题,或者在同系统间传输文件时出现编码问题,所以想了解BOM的结构和作用。 接下来要分点解释: 1. BOM的定义和作用:解释BOM是什么,为什么需要它,比如帮助程序识别编码和字节顺序。 2. 同编码中的BOM表示:比如UTF-8的BOM是EF BB BF,UTF-16 LE/BE的BOM值。 3. BOM的优缺点:在哪些情况下推荐使用,哪些情况下推荐,比如在Unix系统中可能推荐使用BOM。 4. 实际应用场景:比如在Windows记本中使用BOM的情况,其他文本编辑器的处理方式。 5. 如何检测和操作BOM:用户可能需要知道如何查看或删除BOM,可以使用工具或代码示例。 需要确保语言通俗易懂,避免过于技术化的术语,但也要准确。可能用户想知道如何处理带有BOM的文件,或者为什么他们的文件开头有可见的字符,导致程序解析出错。比如在编程中,如果文件有BOM,某些解析器可能会出错,这时候需要移除BOM。 另外,要注意同操作系统和软件对BOM的处理差异,比如Windows和Linux的同做法。可能需要提到在Web开发中,如HTML、CSS文件是否应该包含BOM,通常是推荐的,以免影响浏览器解析。 最后,总结BOM的使用建议,帮助用户根据实际情况决定是否使用BOM。可能用户在使用Qt处理文件时遇到了BOM相关的问题,需要明确在同编码下如何处理BOM,比如使用QTextStream时设置编码方式。</think>--- ### 一、BOM 的定义与作用 **BoM(Byte Order Mark,字节顺序标记)** 是位于文本文件开头的特殊标记字符,用于: 1. **标识文件编码格式**(如UTF-8/UTF-16/UTF-32) 2. **指示字节序**(大端序Big-Endian或小端序Little-Endian,仅对多字节编码如UTF-16/32有意义) 3. **兼容性标记**:帮助程序自动识别编码,避免乱码 --- ### 二、同编码的BOM表示 | 编码格式 | 十六进制值 | 字节序列(HEX) | 常见场景 | |------------|-------------------|---------------|--------------| | **UTF-8** | `EF BB BF` | `0xEF 0xBB 0xBF` | Windows记本默认添加 | | **UTF-16 LE** | `FF FE` | `0xFF 0xFE` | Windows API常用 | | **UTF-16 BE** | `FE FF` | `0xFE 0xFF` | 网络传输/旧系统 | | **UTF-32 LE** | `FF FE 00 00` | `0xFF 0xFE 0x00 0x00` | 极少使用 | | **UTF-32 BE** | `00 00 FE FF` | `0x00 0x00 0xFE 0xFF` | 极少使用 | --- ### 三、BOM的典型应用场景 1. **Windows系统**: - 记本保存UTF-8文件时自动添加BOM - 部分旧版软件依赖BOM识别编码 2. **跨平台文件交换**: - 确保Linux/macOS正确识别Windows生成的文件 - 示例:CSV文件在Excel中打开时需BOM避免乱码 3. **编程开发**: ```cpp // C++读取带BOM的文件示例 QFile file("data.txt"); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); in.setAutoDetectUnicode(true); // 自动检测BOM QString content = in.readAll(); } ``` --- ### 四、BOM的争议与注意项 #### 优点 - 明确声明编码,减少解码错误 - 兼容旧系统/软件 #### 缺点 1. **UTF-8的BOM争议**: - Unix/Linux系统工具(如gcc)可能将BOM视为普通字符,导致脚本执行错误 - Web标准(HTML5/CSS)明确禁止使用BOM 2. **文件尺寸影响**: - UTF-8 BOM增加3字节 - UTF-16 BOM增加2字节 --- ### 五、BOM操作实践指南 #### 检测BOM(Linux命令) ```bash file example.txt # 显示文件编码信息 hexdump -C -n 4 example.txt # 查看文件头4字节 ``` #### 删除BOM(Python示例) ```python with open('file.txt', 'r', encoding='utf-8-sig') as f: # '-sig'自动跳过BOM content = f.read() with open('new_file.txt', 'w', encoding='utf-8') as f: # 无BOM写入 f.write(content) ``` #### 添加BOM(Qt示例) ```cpp QFile file("output.txt"); if(file.open(QIODevice::WriteOnly)) { QTextStream out(&file); out.setGenerateByteOrderMark(true); // 启用BOM生成 out.setCodec("UTF-8"); out << "带BOM的中文内容"; } ``` --- ### 六、各领域推荐方案 | 场景 | 建议 | 理由 | |---------------|------------------|---------------------| | Web开发(HTML/CSS) | 禁用BOM | 遵守W3C标准,避免解析问题 | | Windows程序开发 | 使用BOM | 确保与其他微软系软件兼容 | | Linux脚本 | 禁用BOM | 避免Shebang(如`#!/bin/bash`)失效 | | 跨平台数据文件 | 按需添加BOM | 优先考虑主要使用环境的兼容性 | --- ### 七、经典问题解析 **Q:为什么我的Python脚本执行时报错 `SyntaxError: Non-UTF-8 code`?** A:可能因文件包含UTF-8 BOM导致解释器无法识别Shebang行。解决方案: 1. 用编辑器保存为无BOM的UTF-8格式 2. 或添加编码声明: ```python # -*- coding: utf-8 -*- ``` --- 通过理解BOM的底层原理和应用场景,开发者可以更精准地控制文件编码行为,避免乱码问题。在Qt开发中,建议通过`QTextStream::setGenerateByteOrderMark()`显式控制BOM生成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值