前端开发必知:5个浏览器原生API,比你自己封装的更好用

更新日期: 2026-04-04 阅读: 19 标签: API

前端开发里有很多“重复造轮子”的操作:自己封装复制到剪贴板、手写页面可见性监听、用定时器轮询网络状态……

其实浏览器早就内置了这些API,很多人只是不知道。今天整理5个,每一个都是“知道了就再也回不去”的那种。


1. Clipboard API:一行代码实现复制

以前你是不是这样写复制功能的?

// 老写法:繁琐又 hack
function copyText(text) {
  const input = document.createElement('input');
  input.value = text;
  document.body.appendChild(input);
  input.select();
  document.execCommand('copy');
  document.body.removeChild(input);
}

现在只需要:

// 现代写法
async function copyText(text) {
  await navigator.clipboard.writeText(text);
  console.log('复制成功!');
}

读取剪贴板内容:

async function pasteText() {
  const text = await navigator.clipboard.readText();
  console.log('剪贴板内容:', text);
}

完整的一键复制按钮示例:

const btn = document.querySelector('#copy-btn');
const code = document.querySelector('#code-block').textContent;

btn.addEventListener('click', async () => {
  try {
    await navigator.clipboard.writeText(code);
    btn.textContent = '已复制';
    setTimeout(() => btn.textContent = '复制代码', 1500);
  } catch (err) {
    console.error('复制失败:', err);
  }
});

兼容性:Chrome 66+、Firefox 63+、Safari 13.1+。注意需要HTTPS或localhost环境,否则API不可用。


2. Page Visibility API:页面隐藏时暂停操作

用户切换到其他标签页时,你的视频还在播放、定时器还在跑、请求还在发——这不仅浪费资源,体验也不好。

Page Visibility API让你精确感知页面是否可见:

// 监听页面可见性变化
document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    // 页面隐藏:暂停播放、停止轮询
    video.pause();
    clearInterval(pollingTimer);
    console.log('页面隐藏,已暂停');
  } else {
    // 页面重新可见:恢复播放、重启轮询
    video.play();
    pollingTimer = startPolling();
    console.log('页面可见,已恢复');
  }
});

实际场景:自动暂停轮播图

let autoplay;

function startAutoplay() {
  autoplay = setInterval(() => nextSlide(), 3000);
}

function stopAutoplay() {
  clearInterval(autoplay);
}

// 切换标签页时自动暂停/恢复
document.addEventListener('visibilitychange', () => {
  document.hidden ? stopAutoplay() : startAutoplay();
});

startAutoplay();

查看当前可见状态:

console.log(document.visibilityState);
// 'visible'  - 页面可见
// 'hidden'   - 页面隐藏(切换标签、最小化)
// 'prerender'- 页面正在预渲染(不常见)

兼容性:Chrome 33+、Firefox 18+、Safari 7+,放心用。


3. Network Information API:感知网络质量

你有没有想过,在弱网环境下自动切换低清图片、跳过自动播放视频?Network Information API就是干这个的:

const connection = navigator.connection
  || navigator.mozConnection
  || navigator.webkitConnection;

if (connection) {
  console.log('网络类型:', connection.effectiveType);
  // '4g' | '3g' | '2g' | 'slow-2g'

  console.log('下行速度:', connection.downlink, 'Mbps');
  console.log('往返延迟:', connection.rtt, 'ms');
  console.log('节省数据模式:', connection.saveData);
}

根据网络质量动态加载图片:

function getImageSrc(highRes, lowRes) {
  const connection = navigator.connection;

  // 弱网或开启数据节省模式,用低清图
  if (connection) {
    const isSlowNetwork = ['slow-2g', '2g', '3g'].includes(connection.effectiveType);
    if (isSlowNetwork || connection.saveData) {
      return lowRes;
    }
  }

  return highRes;
}

// 使用
img.src = getImageSrc('photo-4k.jpg', 'photo-thumb.jpg');

监听网络变化:

navigator.connection?.addEventListener('change', () => {
  const type = navigator.connection.effectiveType;
  if (type === '4g') {
    loadHighQualityContent();
  } else {
    loadLightContent();
  }
});

兼容性:Chrome 61+、Android WebView 50+。Firefox和Safari支持有限,使用时建议做if (navigator.connection)判断。


4. matchMedia():JS里监听媒体查询变化

响应式设计不只是CSS的事,有时候JS也需要知道当前是手机还是桌面——比如动态加载不同的组件、切换交互方式。

很多人会用window.innerWidth轮询,其实有更好的方式:

// 不推荐:窗口resize时每次都计算
window.addEventListener('resize', () => {
  if (window.innerWidth < 768) {
    // 移动端逻辑
  }
});

// 推荐:直接监听媒体查询
const mql = window.matchMedia('(max-width: 768px)');

// 初始状态
console.log('是否移动端:', mql.matches);

// 监听变化(窗口大小改变时触发)
mql.addEventListener('change', (e) => {
  if (e.matches) {
    console.log('切换到移动端');
    loadMobileComponent();
  } else {
    console.log('切换到桌面端');
    loadDesktopComponent();
  }
});

监听深色模式切换:

const darkMode = window.matchMedia('(prefers-color-scheme: dark)');

// 当前模式
console.log('深色模式:', darkMode.matches);

// 用户切换系统主题时触发
darkMode.addEventListener('change', (e) => {
  document.body.classList.toggle('dark', e.matches);
});

封装成工具函数:

function onMediaChange(query, callback) {
  const mql = window.matchMedia(query);
  callback(mql.matches); // 立即执行一次
  mql.addEventListener('change', (e) => callback(e.matches));
  return () => mql.removeEventListener('change', callback); // 返回清理函数
}

// 使用
const cleanup = onMediaChange('(max-width: 768px)', (isMobile) => {
  console.log('isMobile:', isMobile);
});

// 组件卸载时清理
// cleanup();

兼容性:Chrome 9+、Firefox 6+、Safari 5.1+,全面兼容,放心用。


5. requestIdleCallback():利用空闲时间做低优先级任务

你需要在页面加载后做一些不紧急的工作——埋点上报、预加载、缓存更新——但不想影响用户交互的流畅度。

requestIdleCallback专门解决这个问题:浏览器在每帧空闲时调用你的回调,不抢占用户交互所需的时间:

// 用setTimeout凑合:不知道什么时候浏览器有空
setTimeout(() => {
  sendAnalytics();
}, 0);

// 推荐:浏览器空闲时再执行
requestIdleCallback((deadline) => {
  // deadline.timeRemaining() 返回当前帧剩余空闲毫秒数
  console.log('空闲时间:', deadline.timeRemaining(), 'ms');

  sendAnalytics();
  preloadNextPage();
});

处理任务队列,超时兜底:

const tasks = [
  () => sendAnalytics(),
  () => preloadImages(),
  () => updateLocalCache(),
];

function runTasksInIdle(tasks) {
  let index = 0;

  function runNext(deadline) {
    // 当还有空闲时间 且 还有任务时,继续执行
    while (deadline.timeRemaining() > 1 && index < tasks.length) {
      tasks[index++]();
    }

    // 还有剩余任务,下一次空闲继续
    if (index < tasks.length) {
      requestIdleCallback(runNext);
    }
  }

  // timeout: 最迟2000ms内必须执行(兜底)
  requestIdleCallback(runNext, { timeout: 2000 });
}

runTasksInIdle(tasks);

兼容性:Chrome 47+、Firefox 55+。Safari不支持,降级方案:

const rIC = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));

总结

API用途替代什么最低兼容
Clipboard API读写剪贴板execCommand('copy') hackChrome 66+
Page Visibility API感知页面是否可见定时器轮询Chrome 33+
Network Information API感知网络类型/速度无(以前做不到)Chrome 61+
matchMedia()JS里监听媒体查询resize事件 + innerWidthChrome 9+
requestIdleCallback()空闲时执行低优先级任务setTimeout(fn, 0)Chrome 47+

这5个API都是浏览器多年前就支持的成熟特性,不需要任何依赖,不用npm install,直接用就行。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13571

相关推荐

适合写api接口文档的管理工具有哪些?

现在越来越流行前后端分离开发,使用ajax交互。所以api接口文档就变的十分有意义了,目前市场有哪些比较优秀的接口文档管理工具呢?比如:MinDoc,eoLinker,apizza,RAML,Swagger等等

前后端分离,如何防止api接口被恶意调用或攻击

无论网站,还是App目前基本都是基于api接口模式的开发,那么api的安全就尤为重要了。目前攻击最常见的就是“短信轰炸机”,由于短信接口验证是App,网站检验用户手机号最真实的途径,使用短信验证码在提供便利的同时,也成了呗恶意攻击的对象,那么如何才能防止被恶意调用呢?

超赞的腾讯短网址(微信url.cn短链接)生成api接口

腾讯短网址的应用场景很广,譬如短信营销、邮件推广、微信营销、QQ营销、自媒体推广、渠道推广等,都会用到短网址。究其原因是在于短网址可以降低推广成本、用户记忆成本,提高用户点击率;在特定的场景下推广还能规避关键词,防止域名被拦截

JSON API免费接口_ 免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口

整理提供最新的各种免费JSON接口,其中有部分需要用JSONP调用。方面前端同学的学习或在网站中的使用,包括:免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口

ACE Editor在线代码编辑器的API使用文档

ACE 是一个开源的、独立的、基于浏览器的代码编辑器,可以嵌入到任何web页面或JavaScript应用程序中。ACE支持超过60种语言语法高亮,并能够处理代码多达400万行的大型文档

浏览器中的图像识别 API

在 Native 开发中,Android 和 IOS 平台都在系统层面直接提供给了应用开发识别图像的一些能力,比如对于二维码/条形码的识别,Android 可以使用 barcode API 、 iOS 可以使用 CIQRCodeFeature API 。

Vue 3.0 体验 Vue Function API

近 Vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并发布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前体验 Vue 3.0 版本的 Function-based component API

vue-next 函数式 api

在分享 vue-next 各个子模块的实现之前,我觉的有必要比较全面的整理下 vue-next 中提出的函数式 api,了解这些的话,无论是对于源码的阅读,还是当正式版发布时开始学习,应该都会有起到一定的辅助作用

在原生 React Native 应用中使用 Expo API

你可以在任何 React Native 应用程序中使用尽可能少或尽可能多的 Expo SDK。 我们已经花了很多时间构建和维护这些包含原生应用特性的跨平台 API,我们很高兴最终实现了向整个 React Native 生态共享这些 API

构建API的最佳编程语言是什么?

你是否正在设计第一个Web应用程序?也许你过去已经建立了一些,但是目前也正在寻找语言的变化以提高你的技能,或尝试新的东西。有了所有信息,就很难决定为下一个产品或项目选择哪种编程语言。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!