阅读视图

发现新文章,点击刷新页面。

妙用 localeCompare 获取汉字拼音首字母

在前端开发中,开发者通常会使用 localeCompare 来进行中文字符的排序比较。但 localeCompare 还有一种较为少见的应用场景 —— 通过获取中文字符的拼音首字母来实现检索功能。本文将详细介绍这一实用技巧及其应用。

原理

localeCompare 方法允许字符串按特定语言环境的排序规则进行比较。在中文环境下,它会默认按照汉字的拼音顺序进行排序。基于这一特性:

  1. 准备一组具有代表性的汉字作为基准点(每个字代表一个拼音首字母的起始位置)
  2. 将目标汉字与这些基准字进行 localeCompare 比较
  3. 根据比较结果确定目标汉字的拼音首字母范围

这种方法无需依赖第三方拼音库,实现简单且轻量,适合大多数基础场景。

应用场景

获取汉字拼音首字母在中文应用开发中有广泛的应用场景:

  • 联系人列表排序:按拼音首字母对联系人进行分组排序
  • 城市选择器:按首字母索引快速定位城市
  • 拼音搜索:将拼音首字母存储到数据库中,用户输入拼音首字母即可检索相关内容
  • 数据分类展示:将中文数据按拼音首字母进行分类展示

核心代码

下面是获取汉字拼音首字母的核心函数实现:

/**
 * 获取汉字的拼音首字母
 * @param chineseChar 中文字符串,若传入多字符则只取第一个字符
 * @param useUpperCase 是否返回大写字母,默认为false(小写)
 * @returns 拼音首字母,若无法识别则返回空字符串
 */
export const getTheFirstLetterForPinyin = (chineseChar: string = '', useUpperCase: boolean = false): string => {
    // 兼容性检查:确保浏览器支持 localeCompare 方法
    if (!String.prototype.localeCompare) {
        return '';
    }

    // 参数验证:确保输入为有效字符串
    if (typeof chineseChar !== 'string' || !chineseChar.length) {
        return '';
    }

    // 准备用于比较的字母表和基准汉字
    // 注:这些基准汉字分别对应A、B、C...等拼音首字母的起始位置
    const letters = 'ABCDEFGHJKLMNOPQRSTWXYZ'.split('');
    const zh = '阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀'.split('');

    let firstLetter = '';
    const firstChar = chineseChar[0];

    // 处理字母和数字:直接返回原字符
    if (/^\w/.test(firstChar)) {
        firstLetter = firstChar;
    } else {
        // 处理汉字:通过比较确定拼音首字母范围
        letters.some((item, index) => {
            // 检查当前字符是否在当前基准汉字与下一个基准汉字之间
            if (firstChar.localeCompare(zh[index]) >= 0 && 
                (index === letters.length - 1 || firstChar.localeCompare(zh[index + 1]) < 0)) {
                firstLetter = item;
                return true;
            }
            return false;
        });
    }

    // 根据参数决定返回大写还是小写字母
    return useUpperCase ? firstLetter.toUpperCase() : firstLetter.toLowerCase();
}

实用示例

获取单个汉字的拼音首字母

// 获取单个汉字的拼音首字母
getTheFirstLetterForPinyin('你'); // => 'n'
getTheFirstLetterForPinyin('好', true); // => 'H'
getTheFirstLetterForPinyin('123'); // => '1'
getTheFirstLetterForPinyin(''); // => ''

获取字符串的拼音首字母缩写

/**
 * 获取整个字符串的拼音首字母缩写
 * @param str 输入字符串
 * @returns 拼音首字母缩写
 */
function getPinyinInitials(str: string): string {
    return str.split('')
        .map(char => getTheFirstLetterForPinyin(char))
        .join('');
}

getPinyinInitials('你好世界'); // => 'nhsj'
getPinyinInitials('JavaScript中文教程'); // => 'javascriptzwjc'
getPinyinInitials('加油123'); // => 'jy123'

联系人列表按首字母分组

// 将联系人列表按拼音首字母分组
function groupContactsByInitial(contacts: {name: string}[]): Record<string, {name: string}[]> {
    const groups: Record<string, {name: string}[]> = {};
    
    // 按首字母分组
    contacts.forEach(contact => {
        const initial = getTheFirstLetterForPinyin(contact.name, true);
        if (!groups[initial]) {
            groups[initial] = [];
        }
        groups[initial].push(contact);
    });
    
    return groups;
}

const contacts = [
    {name: '张三'},
    {name: '李四'},
    {name: '王五'},
    {name: '赵六'}
];

// 按首字母分组
const groupedContacts = groupContactsByInitial(contacts);

// 还可以进一步通过 localeCompare 实现组内排序,此处暂时不做操作
/*
结果:
{
    'L': [{name: '李四'}],
    'W': [{name: '王五'}],
    'Z': [{name: '张三'}, {name: '赵六'}]
}
*/

局限性与替代方案

localeCompare 方法在现代浏览器中得到广泛支持(除了 IE11 前的版本不可用之外,其余浏览器均完全支持)。

局限性

  1. 多音字问题:该方法无法处理多音字情况,例如"音乐"会被识别为"yl"而非"yy"
  2. 准确性限制:对于一些生僻字,可能无法准确识别其拼音首字母
  3. 依赖浏览器实现:不同浏览器的 localeCompare 实现可能略有差异

替代方案

如果需要更强大的拼音处理功能,可以考虑使用以下第三方库:

  • pinyin-pro:支持多音字识别、音调标注等高级功能
  • pinyinjs:轻量级的拼音转换库

通过 localeCompare API,可以在不依赖第三方库的情况下,快速实现中文拼音首字母的获取功能,为您的应用添加更加友好的中文处理能力。

Chrome DevTools 详解(二):Console 面板

在浏览器中,当你按下 F12Ctrl+Shift+I 后,看到的不仅仅是一堆标签,而是一个功能强大的集成开发环境 (IDE)。是浏览器开发者工具(以 Chrome DevTools 为例)中各个核心面板的界面布局、核心功能区域和使用技巧

打开开发者工具后,通常呈现为一个可停靠(Dock)的窗口,可停靠在浏览器窗口的右侧、底部或独立成窗

  • 顶部 Tab 栏:包含 ElementsConsoleSources 等主要面板标签。
  • 主工作区:点击不同标签,显示对应面板的详细内容。
  • 侧边栏 (Sidebar) :通常位于主工作区的右侧或下方,提供更精细的设置和信息(如 Styles, Computed, Event Listeners 等)。
  • 工具栏 (Toolbar) :位于顶部或面板内部,包含搜索、过滤、刷新、设备模拟等快捷按钮。

image.png

浏览器控制台打开的样式,下边会详细解读一下,每个面板都是一个强大的工具:

  • Elements 是 UI 显微镜
  • Console 是 命令行终端
  • Sources 是的 代码手术室
  • Network  网络雷达
  • Performance & Memory 是 性能诊断仪
  • Application 是 应用控制中心
  • Lighthouse 是 自动化质检员
  • Redux DevTools 是 外部插件,react的状态管理工具。

好的,我们来详细解读浏览器开发者工具(以 Chrome DevTools 为例)中各个核心面板的界面布局、核心功能区域和使用技巧。当你按下 F12Ctrl+Shift+I 后,看到的不仅仅是一堆标签,而是一个功能强大的集成开发环境 (IDE)。


Console (控制台) 面板

image.png

核心定位

Console 不只是一个“打印日志的地方”,它是:

  • JavaScript 执行环境(即时运行代码)
  • 调试信息中心(错误、警告、日志)
  • DOM 操作终端(快速查询和修改页面)
  • 性能分析工具(计时、内存检查)
  • 数据导出接口(复制数据供分析)

一、界面布局详解(结合实战)

1. 主日志区 (Main Log Area)

显示内容:
  • console.log() → 普通日志(灰色/黑色)
  • console.warn() → 警告(黄色 )
  • console.error() → 错误(红色 ,带堆栈)
  • console.info() → 信息(蓝色 )
  • 网络错误、语法错误、未捕获异常等
    <script>
      console.log("log");
      console.warn("warn");
      console.error("error");
      console.info("info");
    </script>

image.png

实战演示:
console.log('用户登录成功', { user: 'Alice', id: 123 });
console.warn('此 API 已废弃,请使用 newAPI()');
console.error('请求失败:404 Not Found', new Error().stack);
console.info('页面加载完成');

image.png

效果

  • 对象 { user: 'Alice', id: 123 } 可点击展开
  • console.error() 附带调用栈,点击文件名跳转到 Sources 面板

image.png

跳转后:

image.png

技巧:按住 Ctrl(Win)或 Cmd(Mac)点击堆栈中的文件名,可直接在 Sources 面板打开并定位到那一行。


2. 底部 - 命令行 (Command Line)

一个即时 JavaScript 执行器,相当于页面内的“Node.js REPL”。

1. 查询元素
document.getElementById('app')
  • 作用:通过 id 属性查找 DOM 元素。
  • 解释:在命令行输入这行代码,会返回 id="app" 的 DOM 元素对象(如果存在)。如果元素存在,控制台会显示该元素的 HTML 片段(如 <div id="app">...</div>);如果不存在,返回 null
  • 用途:快速验证某个元素是否存在。

image.png

document.querySelector('.btn-primary')
  • 作用:使用 CSS 选择器查找第一个匹配的元素。
  • 解释:查找 class 包含 btn-primary 的第一个元素。功能比 getElementById 更强大,支持复杂选择器(如 'div > p:first-child')。
  • 用途:调试样式或交互时,快速定位元素。

image.png

2. 修改页面
$0.style.backgroundColor = 'yellow';
  • $0:这是 Command Line API 提供的一个特殊变量。它自动指向你在 Elements 面板中最后选中的那个 DOM 元素
  • .style.backgroundColor:访问该元素的 style 对象,并修改其 background-color CSS 属性。
  • 'yellow' :将背景色设置为黄色。
  • 效果立即生效!你不需要刷新页面,就能看到选中的元素背景变黄。这是一种实时、非破坏性的样式调试方式。
  • 用途:临时修改样式测试效果,或者高亮某个元素以便观察。

image.png

3. 调用函数
myFunction();
  • 作用:调用在页面全局作用域中定义的名为 myFunction 的函数。
  • 解释:只要 myFunction 是全局变量(即 window.myFunction 存在),你就可以在命令行中直接调用它。
  • 用途:测试工具函数、触发页面逻辑、调试。
<body>
  <h1 id="title">Hello, World!</h1>
  <p class="status">状态:待命</p>
  <button onclick="myFunction('用户')">点击我调用 myFunction</button>

  <script>
    // 这是一个全局函数,可以在控制台直接调用
    function myFunction(name = "匿名") {
      console.log(`🎉 函数被调用了!参数 name 的值是: "${name}"`);

      // 修改页面内容
      const titleElement = document.getElementById('title');
      titleElement.textContent = `你好,${name}!`;

      const statusElement = document.querySelector('.status');
      statusElement.textContent = `状态:已激活 (来自 ${name})`;
      statusElement.style.color = 'blue';

      // 返回一个值
      return `问候语已更新给 ${name}`;
    }

    // 额外:一个没有参数的函数
    function greetEveryone() {
      console.log("👋 向所有人问好!");
      return myFunction("所有人");
    }
  </script>
</body>

image.png

4. 查看变量
window.myGlobalVar
  • 作用:访问全局变量 myGlobalVar
  • 解释:在浏览器中,全局变量是 window 对象的属性。window.myGlobalVar 等同于直接写 myGlobalVar(如果它在当前作用域可见)。
  • 用途:检查某个全局状态或配置的值。

image.png

5.支持多行输入:交互式编程

按 Enter 执行单行 按 Shift + Enter 换行,不执行 写完后按 Enter 执行整个代码块

这是命令行的一个非常重要的特性,让你可以编写更复杂的代码片段。

示例代码块
for (let i = 0; i < 3; i++) {
  console.log(i);
}
  • 操作流程

    1. 在命令行输入 for (let i = 0; i < 3; i++) {,然后按 Shift + Enter。光标会移动到下一行,但代码不会执行
    2. 输入 console.log(i);,再按 Shift + Enter
    3. 输入 },最后按 Enter
    4. 此时,整个 for 循

image.png

3. 顶部工具栏:高效过滤与管理

image.png

上图序号对比 按钮 用途 实战场景
1 All / Errors / Warnings / Info / Logs 过滤日志类型 调试时只看 Errors,忽略 Logs
2 清除按钮 清空控制台 刷新后重新开始调试
3 下拉图标 切换执行上下文 展示并切换当前页面中不同的 JavaScript 执行环境
3 小眼睛图标 高亮显示表达式结果 执行输入的表达式,并将返回的 DOM 元素在页面上高亮,同时在 Elements 面板中选中它。
4 搜索框 搜索日志内容 查找 "failed" 相关错误
5 All / Errors / Warnings / Info / Logs 过滤日志类型 调试时只看 Errors,忽略 Logs
6 设置按钮 打开设置 启用 Preserve logConsole timestamp
关键设置推荐
  • Preserve log:勾选后,刷新页面日志不丢失!适合调试页面加载过程。
  • Console timestamp:显示每条日志的时间戳。
  • Hide network messages:关闭后可看到所有网络请求日志。

二、高阶使用技巧(开发必备)

1. console.table():优雅展示数组/对象

const users = [
  { name: 'Alice', age: 25, role: 'Dev' },
  { name: 'Bob', age: 30, role: 'Designer' },
  { name: 'Charlie', age: 35, role: 'PM' }
];

console.table(users);

效果:以表格形式展示,清晰易读,支持排序。

适用场景:调试 API 返回的列表数据。

image.png

2. console.time() / console.timeEnd():性能计时

console.time('API 请求耗时');
fetch('/api/data')
  .then(res => res.json())
  .then(data => {
    console.timeEnd('API 请求耗时'); // 输出: API 请求耗时: 342ms
  });

用途:测量函数执行时间、网络请求延迟、渲染性能。

这代码可以直接跑的,可以自己试一下:


  <body>
    <h1>打开控制台查看结果</h1>
    <p>正在请求一个测试 API...</p>
    
    <script>
      // 开始计时
      console.time("API 请求耗时");

      // 使用一个公开的测试 API(JSONPlaceholder)
      fetch("https://jsonplaceholder.typicode.com/posts/1")
        .then((response) => {
          // 检查响应状态
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          // 将响应体解析为 JSON
          return response.json();
        })
        .then((data) => {
          // 请求成功,JSON 解析完成
          console.log(" 请求成功,收到数据:", data);

          // 结束计时并输出耗时
          console.timeEnd("API 请求耗时");
          // 输出示例: API 请求耗时: 123.45ms
        })
        .catch((error) => {
          // 捕获并处理任何错误(网络错误、解析错误、HTTP 错误)
          console.error(" 请求失败:", error);

          // 即使失败,也应该结束计时,避免计时器一直开着
          console.timeEnd("API 请求耗时");
        });
    </script>
  </body>

image.png

3. console.group() / console.groupEnd():分组日志

console.group('用户操作流程');
console.log('1. 页面加载');
console.log('2. 用户点击按钮');
console.log('3. 发送请求');
console.groupEnd();

console.group('错误详情');
console.error('请求失败');
console.groupEnd();

效果:日志可折叠,结构清晰,适合复杂流程调试。

image.png

4. copy():快速复制数据

const data = { token: 'abc123', user: { id: 1, name: 'Alice' } };
copy(data);

效果:对象被复制为 JSON 字符串到剪贴板,可直接粘贴到 Postman、文档等地方。

用途:调试 API 参数、分享数据结构。


5. $0, $1, $2...:快速引用元素

  • $0Elements 面板中最后选中的元素
  • $1:倒数第二个选中的元素
  • 依此类推(最多保存 5 个)
// 在 Elements 面板选中一个按钮
$0.click(); // 触发点击
$0.innerText = '已提交';

用途:无需 document.querySelector,快速操作页面元素。


6. Command Line API 快捷函数

函数 用途 示例
$(selector) 等价于 document.querySelector() $('.btn')
$$(selector) 等价于 document.querySelectorAll() $$('.list-item')
copy(object) 复制对象到剪贴板 copy({a:1})
keys(object) 获取对象所有键 keys($0)
values(object) 获取对象所有值 values($0.style)
clear() 清空控制台 clear()

三、真实开发场景应用

场景 1:调试异步错误

setTimeout(() => {
  undefinedFunction(); // 报错
}, 1000);
  • 错误出现后,点击堆栈中的 script.js:2 → 跳转到 Sources 面板定位问题。

场景 2:分析 API 返回数据

fetch('/api/users')
  .then(res => res.json())
  .then(data => {
    console.table(data); // 表格化展示
    copy(data); // 复制数据用于测试
  });

场景 3:性能优化

console.time('渲染耗时');
renderLargeList();
console.timeEnd('渲染耗时');

场景 4:快速修改样式(无需 Elements 面板)

$('.header').style.backgroundColor = 'red';
$$('.card').forEach(el => el.style.border = '1px solid blue');

四、注意事项

  1. 不要在生产环境留下 console.log

    • 使用 ESLint 规则 no-console 防止误提交。
    • 构建工具(如 Webpack)会自动移除。
  2. Preserve log 的副作用

    • 日志过多可能占用内存,调试完成后建议关闭。
  3. 安全风险

    • copy() 可能泄露敏感数据(如 token),注意清理。

总结:Console 面板使用心法

目的 推荐方法
打印日志 console.log()
查看结构化数据 console.table()
测量性能 console.time()
组织日志 console.group()
复制数据 copy(data)
快速操作 DOM $(selector), $0
过滤信息 使用顶部过滤器
保留日志 勾选 Preserve log

Console 面板是前端开发者的“第一现场”
无论是调试、探索、测试还是优化,打开 Console,输入一行代码,世界就在你指尖。

Chrome DevTools 详解(一):Elements 面板

在浏览器中,当你按下 F12Ctrl+Shift+I 后,看到的不仅仅是一堆标签,而是一个功能强大的集成开发环境 (IDE)。是浏览器开发者工具(以 Chrome DevTools 为例)中各个核心面板的界面布局、核心功能区域和使用技巧

打开开发者工具后,通常呈现为一个可停靠(Dock)的窗口,可停靠在浏览器窗口的右侧、底部或独立成窗

  • 顶部 Tab 栏:包含 ElementsConsoleSources 等主要面板标签。
  • 主工作区:点击不同标签,显示对应面板的详细内容。
  • 侧边栏 (Sidebar) :通常位于主工作区的右侧或下方,提供更精细的设置和信息(如 Styles, Computed, Event Listeners 等)。
  • 工具栏 (Toolbar) :位于顶部或面板内部,包含搜索、过滤、刷新、设备模拟等快捷按钮。

image.png

浏览器控制台打开的样式,下边会详细解读一下,每个面板都是一个强大的工具:

  • Elements 是 UI 显微镜
  • Console 是 命令行终端
  • Sources 是的 代码手术室
  • Network  网络雷达
  • Performance & Memory 是 性能诊断仪
  • Application 是 应用控制中心
  • Lighthouse 是 自动化质检员
  • Redux DevTools 是 外部插件,react的状态管理工具。

好的,我们来详细解读浏览器开发者工具(以 Chrome DevTools 为例)中各个核心面板的界面布局、核心功能区域和使用技巧。当你按下 F12Ctrl+Shift+I 后,看到的不仅仅是一堆标签,而是一个功能强大的集成开发环境 (IDE)。


Elements (元素) 面板

核心用途:查看、编辑和调试 HTML 结构与 CSS 样式。

image.png

1. 左侧 - DOM 树 (DOM Tree)

以树状结构展示页面的 HTML 元素, 可展开/折叠节点。

  • 双击元素:可直接编辑 HTML 标签或文本内容(临时修改,刷新后失效)。
  • 右键菜单:提供“编辑为 HTML”、“删除节点”、“强制状态”(如 :hover, :active)等选项。

image.png

2. 右侧 - 样式与计算

image.png

标签属性名 核心功能 实际开发
Styles 查看和编辑应用的 CSS 规则 调试样式问题,实时修改
Computed 查看最终计算出的 CSS 值 查看真实尺寸、盒模型、继承值
Layout 可视化 Grid/Flexbox 布局 调试复杂布局
Event Listeners 查看绑定的事件处理函数 调试交互逻辑,查找监听器
DOM Breakpoints 在 DOM 变化时暂停执行 定位修改 DOM 的代码
Properties 查看 DOM 元素的 JS 对象属性 深入了解元素内部结构
Accessibility 检查无障碍属性和对比度 确保网站对所有人可用

1. Styles

Styles 查看和编辑应用的 CSS 规则, 调试样式问题,实时修改。

  • 规则来源:精确到哪个文件的哪一行(可点击跳转到 Sources 面板)。

当你在 Elements 面板Styles 标签页 中查看某个元素的 CSS 样式时,你会看到应用到该元素上的所有 CSS 规则。

  • 来源 (Source) :指的是这条 CSS 规则是从哪里来的
  • 在 DevTools 中,它会明确告诉你这条样式规则定义在哪个 CSS 文件中,以及具体在文件的第几行

具体长什么样?

Styles 面板中,每一条 CSS 规则的下方,通常会显示一个浅色的文本,格式类似于:

text.html:10

或者

main.bundle.css:123
  • styles.css 或 main.bundle.csstext.html:10:这是文件名
  • 42 或 10:这是行号

image.png

可点击跳转到 Sources 面板

这才是最厉害的地方!

  • 你看到的这个 text.html:10 不是一个静态文本,而是一个可点击的链接

  • 当你点击这个text.html:10 时,DevTools 会自动:

    1. 切换到 Sources (源码) 面板
    2. 在左侧的文件树中找到并打开 text.html 这个文件。
    3. 自动滚动并高亮显示第 10 行的代码。

image.png

这功能有什么用处嘞?

想象一下这个场景:

  1. 你在页面上看到一个按钮的样式不对(比如,颜色错了,或者间距太大)。
  2. 你用 Elements 面板 选中这个按钮。
  3. 在 Styles 面板 里,你发现是 color: red; 这条规则导致了问题。
  4. 你看一下这条规则的来源,显示是 theme-overrides.css:88
  5. 直接点击 theme-overrides.css:88
  6. 瞬间,你就跳转到了 theme-overrides.css 文件的第 88 行,看到了那条有问题的 CSS 代码。
  7. 你可以在 Sources 面板 中直接编辑它(如果配置了 Workspaces,甚至能保存到本地文件),或者记下位置去你的代码编辑器里修改。
  • 实时编辑:勾选/取消复选框可启用/禁用某条 CSS 声明;双击值可修改。

image.png

  • 新增样式:在底部的 element.style 区域可添加内联样式。

image.png


2. Computed 标签页

Computed 查看最终计算出的 CSS 值 查看真实尺寸、盒模型、继承值 。

  • 显示该元素最终计算出的所有 CSS 属性值。
  • 盒模型可视化:顶部有一个直观的盒模型图,点击各区域可快速定位到对应的 CSS 属性。
  • 继承属性:可查看从父元素继承的样式。
  • Event Listeners 标签页:列出绑定到该元素的所有事件监听器(包括捕获和冒泡阶段)。
  • Accessibility 标签页:检查无障碍属性(如 aria-*, role, 对比度等)。

使用技巧

  • 使用 Ctrl+F (Cmd+F) 在 DOM 树中搜索元素。
  • 利用“强制状态”调试 :hover, :focus 等伪类样式。
  • 按字母顺序列出所有 CSS 属性及其最终值。
  • 盒模型可视化:顶部有一个图形化的盒模型图,清晰展示 marginborderpaddingcontent 的尺寸。点击各区域可以快速在 Styles 或 Computed 列表中定位到对应的属性。
  • 显示属性的来源:告诉你这个值是从哪个 CSS 规则继承或计算而来的

image.png

使用场景:查看元素的真实尺寸和布局,解决“为什么这个元素占了这么多空间?”的问题。


3. Layout (布局)

  • 作用:提供与元素布局相关的额外信息,特别是CSS Grid 和 Flexbox 布局的可视化调试工具。

  • 内容

Grid Overlay:如果元素是 CSS Grid 容器,这里会列出所有的 Grid 网格线、轨道 (tracks) 和区域 (areas)。勾选一个网格后,页面上会叠加一层半透明的网格线,直观地展示 Grid 布局结构。

   <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: #8a2be2;
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
        gap: 20px;
        padding: 20px;
      }

      .box div {
        width: 20px;
        height: 20px;
        background-color: #7ae22b;
      }
    </style>
  </head>
  <body>
    <div>123</div>
    <div class="box">
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>

    <script>
      console.log("log");
      console.warn("warn");
      console.error("error");
    </script>
  </body>

image.pngFlexbox Overlay:如果元素是 Flex 容器,会显示主轴 (main axis)、交叉轴 (cross axis)、对齐方式等信息,并可以在页面上叠加可视化辅助线。

    <style>
      .box {
        width: 100px;
        height: 100px;
        background-color: #8a2be2;
        display: flex;
        justify-content: space-between;
      }

      .box div {
        width: 20px;
        height: 20px;
        background-color: #7ae22b;
      }
    </style>
  </head>
  <body>
    <div>123</div>
    <div class="box">
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>
  </body>

image.png

使用场景:调试复杂的 Grid 或 Flexbox 布局,确保子元素正确排列。


4. Event Listeners (事件监听器)

  • 作用:查看绑定到当前元素(以及其祖先元素,因为事件冒泡)上的所有 JavaScript 事件监听器。

  • 内容

    • 按事件类型分组(如 clickkeydownmouseover 等)。

    • 对于每个监听器,显示:

      • Listener:监听的函数(如果是命名函数会显示名字,匿名函数则显示 function())。
      • Handler:实际执行的代码片段预览。
      • Location:该监听器定义在哪个文件的哪一行,点击可跳转到 Sources 面板
      • Object:监听器附加到的对象(通常是当前元素或 document 等)。
      • Type:是捕获阶段 (capturing) 还是冒泡阶段 (bubbling)。
      • Remove:可以点击删除该监听器(用于调试)。
<body>
  <div id="container">
    <button id="myButton">点击我</button>
    <input type="text" id="textInput" placeholder="输入点什么">
  </div>

  <script>
    // 1. 命名函数监听器
    function handleButtonClick() {
      console.log('按钮被点击了!');
    }

    // 2. 匿名函数监听器
    document.getElementById('textInput').addEventListener('input', function (e) {
      console.log('输入框内容变化:', e.target.value);
    });

    // 3. 箭头函数监听器(匿名)
    document.getElementById('myButton').addEventListener('click', (e) => {
      console.log('箭头函数:按钮被点击了!');
      // 阻止默认行为(虽然按钮没有默认行为)
      e.preventDefault();
    });

    // 4. 绑定到祖先元素(事件委托)
    document.getElementById('container').addEventListener('click', function (e) {
      if (e.target.id === 'myButton') {
        console.log('事件委托:按钮被点击了!');
      }
    });

    // 5. 捕获阶段监听器
    document.getElementById('myButton').addEventListener('click', function () {
      console.log('【捕获阶段】按钮被点击了!');
    }, true); // 第三个参数为 true,表示在捕获阶段执行

    // 6. 重复绑定(用于演示问题)
    document.getElementById('myButton').addEventListener('click', handleButtonClick);
    document.getElementById('myButton').addEventListener('click', handleButtonClick); // 重复绑定!
  </script>
</body>

  • 点击按钮时,控制台输出顺序为:

    1. 【捕获阶段】按钮被点击了! (捕获阶段)
    2. 箭头函数:按钮被点击了! (目标,冒泡)
    3. 按钮被点击了! (目标,冒泡)
    4. 按钮被点击了! (目标,冒泡) ← 重复绑定导致
    5. 事件委托:按钮被点击了! (冒泡到祖先)

Event Listeners 面板明确标注了 capturing 和 bubbling,更好理解这个执行顺序。 image.png

跳转后:

image.png

  • 高级技巧
  1. 过滤监听器:面板顶部有搜索框,可以输入 clickkeydown 等来过滤。
  2. 查看 window 和 document 监听器:选中 <html> 或 <body> 元素,可以查看全局事件监听器(如 window.onloaddocument.addEventListener('click', ...))。
  3. 调试异步绑定:如果监听器是在 setTimeout 或 AJAX 回调中动态绑定的,确保在绑定完成后刷新 Event Listeners 面板。
  4. 框架应用中的使用:在 React、Vue 等框架中,事件通常由框架管理。你可能会看到框架内部的监听器(如 ReactEventListener)。虽然不直接对应你的代码,但可以帮助你理解框架的事件系统。
  • 使用场景

    • 调试“为什么点击没反应?”——检查是否有监听器被正确绑定。
    • 查找“为什么事件触发了多次?”——检查是否绑定了多个相同的监听器(可能导致内存泄漏)。
    • 理解事件处理逻辑的来源。

5.DOM Breakpoints (DOM 断点)

  • 作用:当前元素的 DOM 结构发生特定变化时,让 JavaScript 执行暂停(中断),方便你调试是哪段代码修改了 DOM。
  • 如何使用这个面板?(操作步骤)
  1. 在 Elements 面板 中选中一个元素(比如 <p id="status">状态:正常</p>)。
  2. 右键点击该元素 → 选择  "Break on"  → 然后选择:
  • Subtree modifications(子节点变化)
  • Attributes modifications(属性变化)
  • Node removal(节点被移除)
  1. 设置成功后,你会看到:
  • 该元素旁边出现一个 小红点(或者其他颜色的点,表示已设置断点)。
  • 同时,在 DOM Breakpoints 面板 中,会出现这个元素和你设置的断点类型。
  1. 当触发对应的变化时,JavaScript 执行会暂停,并跳转到 Sources 面板,高亮出修改代码的那一行。
  • 选项

    • Subtree modifications:当该元素的任何子节点被添加、移除或移动时触发断点。
    • Attributes modifications:当该元素的任何 HTML 属性(如 classiddata-*)被修改时触发断点。(最常用!当你发现某个元素的样式 (class) 或状态 (data-*) 被意外修改时,用它准没错。)
    • Node removal:当该元素本身被从 DOM 树中移除时触发断点。
<body>
  <div id="content">
    <p id="status">状态:正常</p>
    <button id="triggerBtn">触发神秘操作</button>
  </div>


  <script>
    // 模拟一个复杂的、可能出错的“神秘”函数
    function mysteriousOperation() {
      // 1. 修改属性:给 p 元素添加一个 class
      const statusEl = document.getElementById('status');
      statusEl.classList.add('highlight');
      statusEl.textContent = '状态:已高亮';

      // 2. 子树修改:向 #content 添加一个新元素
      const newPara = document.createElement('p');
      newPara.textContent = '这是一个动态添加的段落。';
      document.getElementById('content').appendChild(newPara);

      // 3. 移除节点:移除按钮本身
      document.getElementById('triggerBtn').remove();
    }

    // 绑定按钮点击
    document.getElementById('triggerBtn').addEventListener('click', mysteriousOperation);
  </script>
</body>

image.png

断点生效后,跳转:

image.png

  • 高级技巧与注意事项
  1. 选择正确的元素:确保你设置断点的元素是真正被修改的那个。如果修改的是子元素,可能需要在父元素上设置 Subtree modifications
  2. 避免过度设置:在大型应用中,频繁的 DOM 修改(如动画、轮询)可能导致断点频繁触发,影响调试体验。用完记得删除。
  3. 与常规断点结合使用:可以在 Sources 面板中设置常规断点,然后配合 DOM Breakpoints 来更全面地分析代码流。
  4. 注意性能:开启 DOM Breakpoints 会对页面性能有轻微影响(DevTools 需要监听 DOM 变化),但通常可以忽略。生产环境无需担心。
  5. textContent 的陷阱:修改 textContent 会创建或修改一个 #text 子节点,这会触发 Subtree modifications 断点,而不仅仅是 Attributes modifications
  • 使用场景

    • 你发现某个元素的 class 名字被莫名其妙地改了,但不知道是哪段代码干的。在这里设置“Attributes modifications”断点,刷新页面,当 class 被修改时,DevTools 会自动暂停,并在 Sources 面板 中高亮出修改它的那行 JavaScript 代码。
    • 调试动态内容加载(如 AJAX 更新列表)。

6. Properties (属性)

  • 作用:以 JavaScript 对象的形式,直接展示当前 DOM 元素对象的所有属性和方法。这本质上是 console.dir($0) 的图形化版本。

  • 内容

    • 将 DOM 元素视为一个 JavaScript 对象,列出其所有自有属性和继承自原型链的属性。
    • 包括标准属性(如 idclassNameinnerHTMLstyle)、事件处理函数(如 onclick)、以及各种 DOM API 方法(如 appendChildremove)。
    • 可展开查看嵌套对象(如 style 对象包含所有 CSS 属性)。

image.png

  • 如何使用
  1. 在 Elements 面板 中选中 <button id="myBtn">
  2. 切换到 Console,输入:
console.dir($0);

你会看到类似这样的输出:

HTMLButtonElement
  accessibleNode: AccessibleNode {…}
  attributes: NamedNodeMap [id="myBtn", class="btn primary", data-action="submit", disabled]
  childNodes: NodeList [Text]
  className: "btn primary"
  customData: {version: "1.0", userId: 123}  // ← 你添加的自定义属性
  dataset: DOMStringMap {action: "submit"}
  disabled: true
  id: "myBtn"
  innerHTML: "提交"
  onclick: ƒ ()  // ← 你绑定的事件
  outerHTML: "<button id="myBtn" class="btn primary" data-action="submit" disabled>提交</button>"
  __proto__: HTMLButtonElementPrototype
    appendChild: ƒ appendChild()
    remove: ƒ remove()
    focus: ƒ focus()
    ...

image.png

  • 对比 Properties 面板

Properties 标签页中,你会看到完全相同的结构,但以可展开的树形 UI 呈现:

  1. HTMLButtonElement → 展开后看到所有属性
  2. customData → 可展开查看 {version: '1.0', userId: 123}
  3. onclick → 显示函数定义
  4. __proto__ → 可层层展开,查看继承链
区域 内容 开发价值
$0 当前选中的 DOM 元素对象 你可以直接在控制台使用 $0 引用它
idclassNameinnerHTML 标准 HTML 属性 快速查看/验证元素状态
dataset data-* 属性集合 查看 data-action="submit" → dataset.action
style CSSStyleDeclaration 对象 展开后看到所有行内样式,比 Styles 面板更底层
classList DOMTokenList 查看 addremovetoggle 等方法
onclickonmouseover 事件处理函数 查看是否绑定了原生事件(注意:addEventListener 不会出现在这里)
__proto__ 原型链 查看继承自 HTMLElement → Element → Node 的所有方法
customData (自定义属性) 你手动添加的属性 框架(如 Vue、React)可能注入 _vnode__vue__ 等
  • 高级技巧
  1. 结合 $0 在控制台操作
// 获取当前选中元素
$0;

// 修改其属性
$0.textContent = '已更新';

// 调用方法
$0.focus();

// 查看自定义数据
$0.customData.userId;
  1. 查看 window 或 document 的属性

Elements 面板中选中 <html> 元素,Properties 会显示 HTMLHtmlElement 对象。
如果你想看 window 对象,可以在控制台输入 console.dir(window)

  1. 调试 Shadow DOM

如果元素包含 Shadow DOM,Properties 面板会显示 shadowRoot 属性,你可以展开它查看 Shadow Tree 内部结构。

  • 使用场景

    • 深入了解 DOM 元素的内部结构。
    • 查看元素的 __proto__ 链,理解其继承关系。
    • 检查某些非标准或框架注入的属性。

7. Accessibility (无障碍)

  • 作用:评估当前元素的无障碍 (Accessibility, a11y) 特性,确保残障用户(如视障人士使用屏幕阅读器)也能正常使用你的网站。个人认为啊,它不是可有可无的“加分项”,而是现代 Web 开发的基本要求

  • 内容

    • Name:屏幕阅读器读出的名称。它可能来自 alt 属性、aria-labelaria-labelledby 或元素内的文本。
    • Role:元素的角色(如 buttonlinkheadingimg)。正确的角色帮助屏幕阅读器理解元素的功能。
    • Properties:相关的 ARIA 属性(如 aria-expandedaria-hidden)。
    • Contrast Ratio:文本颜色与背景颜色的对比度。DevTools 会计算并判断是否符合 WCAG 标准(AA 或 AAA 级别),不符合会标红警告。
    • Computed Values:浏览器最终计算出的无障碍属性。
  • 如何使用:

步骤 1: 打开 DevTools 并选中元素

  1. 打开 Chrome DevTools。
  2. 使用元素选择器(或点击 Elements 面板)选中第一个 <button class="icon-btn">⚙️</button>

步骤 2: 切换到 Accessibility 标签页

你会看到类似这样的信息:

属性 问题
Name ⚙️ 错误,屏幕阅读器可能读作“齿轮”或“符号”,不明确
Role button 正确,是按钮角色
Properties - 错误,缺少 aria-label 等辅助信息
Contrast Ratio - -

问题:Name 不明确,用户不知道这是“设置”还是“删除”。

改进方案:添加 aria-label

<button class="icon-btn" aria-label="设置">⚙️</button>

image.png

    <style>
      .icon-btn {
        background: #ccc;
        border: none;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        /* 隐藏文字 */
        font-size: 0;
      }

      /* 低对比度 */
      .text {
        color: #888;
      }
    </style>
  </head>

  <body>
    <!-- 1. 一个没有文本的图标按钮 -->
    <button class="icon-btn">⚙️</button>

    <!-- 2. 一段低对比度的文字 -->
    <p class="text">这是一段灰色文字,背景是白色。</p>

    <!-- 3. 一个正确的按钮 -->
    <button aria-label="设置" aria-expanded="false">⚙️</button>

    <script>
      // 给按钮添加一个自定义属性和事件
      const btn = document.getElementById("myBtn");
      btn.customData = { version: "1.0", userId: 123 };
      btn.onclick = function () {
        console.log("按钮被点击了!");
      };
    </script>
  </body>
  • 使用场景

    • 开发符合无障碍标准的 Web 应用。
    • 调试为什么屏幕阅读器没有正确读出某个按钮的文字。
    • 确保颜色对比度足够,方便色盲或弱视用户阅读。
  • 核心字段深度解析(开发必知)

字段 说明 开发建议
Name 屏幕阅读器“读”出的内容 - 来源:altaria-labelaria-labelledby、内部文本 - 图标按钮必须加 aria-label
Role 元素的“身份”(如 buttonlinkheading - 使用语义化 HTML(<button> 而不是 <div onclick>) - 必要时用 role="button" 修正
Properties ARIA 属性(aria-* aria-expanded: 下拉菜单展开状态 - aria-hidden="true": 隐藏装饰性元素 - aria-live: 动态内容更新提示
Contrast Ratio 文本与背景的对比度 - 正文文本:至少 4.5:1 - 大文本(18pt+):至少 3:1 - 使用 WebAIM Contrast Checker
Computed Values 浏览器最终计算出的 a11y 属性 用于调试“为什么设置了 aria-label 却没生效?”
  • 注意事项
  1. 优先使用语义化 HTML

    • 用 <button> 而不是 <div onclick>
    • 用 <a href> 而不是 <div onclick> 做跳转
    • 语义化元素自带正确的 role 和键盘交互。
  2. 不要滥用 ARIA

    • ARIA 是“补救措施”,不是替代品。
    • 错误使用 ARIA 比不用更糟。
  3. 键盘导航测试

    • 按 Tab 键测试焦点顺序。
    • 确保所有交互元素都能通过键盘操作。
  4. 结合 Lighthouse 使用

    • 在 DevTools 中使用 Lighthouse 生成完整的 a11y 报告,覆盖整个页面。

Accessibility 不是“附加功能”,而是“基本人权”。
使用 Accessibility 面板,你不仅是在调试代码,更是在为每一个用户创造一个更包容、更友好的网络世界。

基于浏览器扩展 API Mock 工具开发探索|得物技术

一、前 言

在日常开发过程中,偶尔会遇到后端接口未完成或者某个环境出现问题需要根据接口返回来复现等等场景。刚好最近在学习浏览器插件的相关知识,并在此背景下开发了一款基于浏览器插件的 Mock 工具。该工具专注于 API 请求拦截和数据模拟,旨在帮助开发者提升开发效率,能够解决一些问题。

二、浏览器插件介绍

什么是浏览器插件

浏览器插件(Extensions 或 Add-ons)是一类运行于浏览器进程中的轻量级功能增强模块,其核心价值在于通过标准化接口实现对浏览器内核能力的深度整合与定制。根据 Mozilla 开发者文档定义,插件本质上是“能够修改和增强浏览器能力的应用程序”,Firefox、Chrome 等主流浏览器均采用 WebExtensions API 这一跨浏览器技术构建插件生态。与网页应用(Web App)需依赖浏览器标签页运行、原生应用(Native App)需独立安装的特性不同,插件以轻量化部署为显著特征——无需复杂设置即可直接在浏览器环境内运行,同时具备标签控制、网络请求拦截、本地存储访问等网页应用无法实现的底层能力。

Manifest V3 架构

Manifest V3 对浏览器插件的底层架构进行了颠覆性重构,主要体现在背景执行机制、网络请求控制和代码安全模型三个核心维度。以下从技术实现与设计动机角度进行全面对比:

关键架构变革:V3 采用"静态声明+内核级处理"模式替代 V2 的"动态脚本+插件自主控制"模式,通过浏览器内核直接介入关键流程(如网络拦截),在性能与安全性之间取得平衡。

核心配置差异示例

背景执行模块配置

// V2 持久化背景页配置"
background": {
  "scripts": ["background.js"],  
  "persistent": true             
}


// V3 Service Worker 配置
"background": {
   "service_worker": "background.js",  
   "type": "module"                   
}

网络请求规则配置

V3 需在 Manifest 中声明 DNR 权限及规则文件:

// V3 declarativeNetRequest 配置
"permissions": ["declarativeNetRequest"],
"host_permissions": ["<all_urls>"],
"declarative_net_request": {
   "rule_resources": [
       {"id": "ruleset_1","enabled": true,"path": "rules.json"  }
    ]
}

三、Mock 插件实现的基本原理

请求拦截的核心原理

由于 Manifest V3 移除了webRequest API 的阻塞能力,declarativeNetRequest又无法重定向到自定义数据,于是方案上选择的是在页面上下文中重写原生 API,目前重写了fetch跟XMLHttpRequest。

// injected.js - 在页面环境中重写fetch
const originalFetch = window.fetch;
window.fetch = async function(url, options = {}) {
  // 1. 发送拦截请求到content script
  const response = await sendMockRequest(url, options);


  // 2. 如果有匹配的Mock规则,返回Mock数据
  if (response.shouldMock) {
    return new Response(
      JSON.stringify(response.mockData),
      {
        status: response.status,
        headers: response.headers
      }
    );
  }


  // 3. 否则执行原始请求
  return originalFetch.call(this, url, options);
};

脚本注入

通过多重注入策略 + 动态检测的方式实现, 直接引入会触发 Content Security Policy 阻止内联脚本执行。

// content.js
async function injectScript() {
  // 策略1: 内联脚本注入
  try {
    await injectInlineScript();
    if (await checkScriptActivation()) return;
  } catch (e) {
    console.warn('内联注入失败:', e);
  }


  // 策略2: 外部脚本注入
  try {
    await injectExternalScript();
    if (await checkScriptActivation()) return;
  } catch (e) {
    console.warn('外部注入失败:', e);
  }


  // 策略3: 最简单注入方式
  await attemptSimpleInjection();
}

四、整体实现架构与流程

项目结构设计

chrome-mock/
├── build-script/          # rollup 进行构建
├── static/                # 静态文件引入,如mockjs
├── debug/                 # 本地调试相关的页面
├── manifest.json          # 插件配置
├── background.js          # 核心逻辑处理
├── content.js            # 脚本注入和消息中转
├── injected.js           # 请求拦截实现
├── options.html          # 管理界面
├── options.js            # 管理界面逻辑
├── options.css           # 管理界面样式
├── popup.html            # 弹窗界面
├── popup.js              # 弹窗逻辑
├── popup.css             # 弹窗样式
└── icons/                # 图标资源

相关功能介绍

创建 Mock 规则

创建 Mock 规则提供了多种方式:

  • 如果是快速联调的场景,可以用得物API管理平台导入的方式。
  • 在排查某个环境问题,需要根据服务端接口返回数据复现的时候,可以通过在管理规则页面手动新建。

方法一:快捷操作弹窗配置

  • 打开 Mock 管理页面
    • 点击浏览器工具栏中的 Mock Frog 图标;
    • 选择"管理规则"或直接访问扩展选项页。
  • 添加新规则

方式一:复制粘贴得物API管理平台地址,点击导入,自动生成。这个弹窗比较小适合自动导入的场景,也可以点击上面 popup 的管理规则再进行操作。

如:https:/apiManage.test.com/project/interface?id=3xxxx&projectId=5xxxx

本地调用可能会有代理增加了前缀,系统会自动在路径前添加通配符 *

方式二:复制接口地址到匹配 URL 输入框中自行配置数据,这一步建议到管理规则中才施展的开。

支持根据接口平台的 JSON Schema 生成对应类型的 Mock 数据。

Mock 效果演示:

,时长00:14

方法二:管理规则页配置

由于 popup 界面大小有限,点击其他区域弹窗也会关闭,提供了一个比较详细的管理页可以修改添加规则。

规则列表:

新建 Mock 规则:

页面白名单管理

作用:针对所有页面都进行拦截可能会导致页面卡顿,影响整体性能,于是增加了白名单控制,控制 Mock 功能在哪些场景下才生效。同时也提供了全局生效模式,方便快速操作。

使用方法:

  • 开启白名单功能
    • 进入扩展设置页面
    • 找到"页面白名单"配置
    • 启用"使用页面白名单"
  • 添加白名单域名
支持格式:
- http://localhost:3000        # 完整URL
- *.example.com               # 通配符域名
- dev.company.com             # 具体域名
- http://dev.company.com      # 带协议的域名

请求日志

作用:记录所有 Mock 请求的详细信息,便于调试。

整体流程

五、总结与收获

本次插件开发过程中,探索了浏览器扩展插件的能力,学习了 Manifest V3 的新知识,掌握了浏览器插件开发相关技术点。随之而来带来的思考便是在 AI 的浪潮下,浏览器插件是否能有更多的可能。

另外,本次很多功能点的实现也依赖了 Cursor,探索浏览器插件的同时也深入的学习了Cursor的应用,感受到了Cursor从 0 到 1 搭建过程中的速度和效率。但是在后续需要对功能点进行改造时,使用效率并不是高,如何建立规则和组织话术,让 AI 更加规范、高效地辅助开发是一个值得深思的问题,当然通过 rules 是能够解决大部分问题。

六、未来展望

功能升级:在复杂业务场景中,往往需要Mock的接口都比较多。如果能监听页面所有请求,然后提供通过选中某个历史请求即可Mock接口的方式,就能快速实现接口的Mock。

能力拓展:探索在浏览器插件上结合 AI 能力的应用,基于规则跟用户的要求更快速的生成 Mock 数据。

往期回顾

1. 破解gh-ost变更导致MySQL表膨胀之谜|得物技术

2. MySQL单表为何别超2000万行?揭秘B+树与16KB页的生死博弈|得物技术

3. 0基础带你精通Java对象序列化--以Hessian为例|得物技术

4. 前端日志回捞系统的性能优化实践|得物技术

5. 得物灵犀搜索推荐词分发平台演进3.0

文 /段壹

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

Chrome 迎来大更新,刚刚登顶 App Store 的 AI 可以直接用了

你应该也有类似的浏览器使用体验,就是当你曾经打开过一个标签页,但是忘了给它添加书签;下次再想找到它时,只能去历史记录里面翻个半天,还不一定能找到。

前些天,我们介绍 Google AI 全家桶的产品指南,它的浏览器 Chrome 被排除在外。

一方面,这是个传统的老牌浏览器,几乎每个人的电脑都有安装一个;另一方面,浏览器本身好像就是没有任何 AI 功能,找标签页这个场景,除了依赖第三方扩展插件,我们只能去翻历史记录。

但是现在,Chrome 进行了自 2008 年发布以来最大的一次升级,找不到的标签页,点击右上角 Gemini 的小图标,一句话就能解决。不管你喜不喜欢,它也是一个 AI 浏览器了。

▲ Gemini in Chrome

点击右上角的 Gemini 图标,我们可以与 Gemini 进行跨标签页的对话

Chrome 不再是一个被动打开网页的工具,Gemini 的引入,让它变成一个能主动帮我们干活的智能伙伴。Gemini 助理、AI 搜索模式、智能体、以及一系列新的安全和便捷功能都来了。

Chrome 在自己的 YouTube 频道和官方博客,发布多条内容,介绍这个「历史全新」的浏览器。我们第一时间研究了所有新功能,可以负责任地告诉你,这不只是加了个聊天机器人那么简单,我们的上网方式可能真的需要一点时间,来学习和适应这个更聪明的浏览器。

信息过载?AI 帮忙画重点,几十个网页秒变一份精华纪要

这可能是打工人和学生党最狂喜的功能。想象一个场景,老板让你半小时内调研完一个行业,或者你需要为论文快速消化十几篇文献。过去,我们只能一篇篇点开,匆忙地在多个标签页切换。

现在,打开这些网站标签页,然后呼叫 Gemini,它就能像一位专业的助理,跨越多个标签页进行阅读、对比和总结。

▲ Gemini in Chrome 能够获取多个标签页的上下文信息

我们可以直接问它:「这几款相机的优缺点分别是什么?」或者「帮我把这些资料整合成一份旅行计划」。它甚至还能找到 YouTube 视频里的关键信息,我们不需要额外的第三方插件,就能得到一样的 YouTube 视频总结。

从大海捞针到 AI 直接递上答案,这效率提升可不止一点半点。

动口不动手,你的浏览器助理未来什么都能干

如果说「总结资料」只是开胃菜,那接下来的「智能体能力」(Agentic Capabilities)就是 Google 为我们描绘的未来图景。

简单来说,和所有智能体一样,我们负责下命令,浏览器负责跑腿。也和所有关于智能体能力的演示一样,我们只能用智能体来预订餐厅,买生日礼物。

Google 提到在未来几个月,通过结合 Google 强大的应用生态,YouTube 视频、Gmail 邮箱、Calendar 日历、以及办公套件等,我们可以直接对 Chrome 说,「帮我订一份常吃的那家沙拉。」、「预约下周三下午的美发。」、「把这些东西加到我的购物车里。」

▲ 集成在 Chrome 里面的 Gemini,有能力为我们处理一些简单的重复性任务

Chrome 会在我们授权后,自动在网页上进行点击、填写、下单等一系列多步骤操作,而我们全程只需监督,随时可以叫停。

虽然听起来有点像 ChatGPT agent 之前演示的功能,但其实就是这样。我觉得智能体的能力,还没有被真正的挖掘出来,专门开发一个 AI 浏览器用来预订餐厅,听起来怎么都不划算。

Chrome 即将更新的智能体能力,我的期待是,我们生活中真正的琐事,可以从需要 30 分钟的处理,变成 3 次点击。

地址栏,现在是 AI 全能框

Chrome 那个我们每天都要用无数次的网页地址栏,现在也升级成为 Omnibox 全能框。

当我们访问一个网页时,地址栏会根据页面内容,智能地为你推荐一些我们可能想问的问题。

比如正在看一款床垫,它可能会提示你:「这个东西的保修政策是啥?」。

▲ AI 模式在地址栏中直接可用

此外,跟我们之前介绍的 AI Mode(AI 模式)有关,现在我们不需要去专门的 Google 搜索地址,直接在地址栏,就能开启 AI 模式。一些更复杂、更开放、需要深度研究的问题,AI Mode 都能做到。

比如「给我推荐几款适合小户型的复古风咖啡机,预算 1000 元以内」,AI 会直接在侧边栏生成一份详尽的报告,无需跳转。

AI 除了用来提升效率,也让 Chrome 更安全

聊了这么多 AI 的功能,安全也是 Chrome 非常在意的一个因素,Chrome 大概想说,不要觉得只有你 Safari 在保护隐私安全。

这次主要是利用 Gemini Nano 模型,能更主动地识别和拦截,那些诱导我们下载有害软件的诈骗网站。

以及对通知更加智能的管理,AI 会自动识别那些垃圾、诈骗类的网站通知,并帮你「一键退订」。Google 称仅在 Android 端,这项功能,每天就能为用户减少约 30 亿次骚扰。

密码的保护也得到了更新,当密码不幸泄露时,Chrome 未来将能像一个密码特工一样,在支持的网站上,直接帮我们一键完成密码修改。

▲ Chrome 可以通过一次点击,修复泄漏的密码

在 Chrome 中的 Gemini,此前是 Google Labs 的项目,仅针对 AI Pro 和 Ultra 用户。

现在 Chrome 的这些更新,支持在美国且将英语设置为首选语言的全部用户,支持 Mac 和 Windows 版本;而 Android 和 iOS 版本也将很快推出,里面部分功能在持续更新中。

🔗 官方使用指南帮助:
https://support.google.com/gemini/answer/16283624

我们之前也多次讨论过 AI 浏览器的形态,无论是 the browser company 曾经推出的 Arc,还是后面集成了更多新功能的 Dia,现在被卖给 Atlassian。

还有 Perplexity 推出的 Comet,最近应该正式向大部分用户开放了,不需要漫长的 waitlist 等候。

以及前段时间微软称 Edge 也正式升级为 AI 浏览器;和关于 OpenAI 的 AI 浏览器传闻。

和这次的 AI Chrome 类似,它们的模式甚至都可以被总结成一个侧边栏,和一个像 ChatGPT 首页的启动页面。

▲ 根据 statcounter 统计数据,Chrome 市场份额全球领先

但是,Chrome 和它们不一样的是,这是一个在全世界范围都遥遥领先的浏览器。今天的更新,可能标志着「AI 浏览器」这个概念,真的要从一些少数派的探索,走向更大众化的讨论。

呈现 AI 最好的形态不是浏览器,那 AI 浏览器最好的形态又该是什么样。

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

爱范儿 | 原文链接 · 查看评论 · 新浪微博


❌