找到
57
篇与
Web前端
相关的结果
-
8 个 CSS Reset 技巧,兼容性问题减少 85% CSS Reset 是构建稳定跨浏览器样式的基础,可以消除 HTML 元素在不同的浏览器中默认样式的差异。分享一些现代化的 CSS Reset 技巧,帮助你解决大部分浏览器兼容性问题,提高开发效率。 图片 1. 现代化盒模型重置 使用更智能的盒模型重置,确保元素尺寸计算的一致性。 *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; /* 防止边距塌陷 */ min-height: 0; min-width: 0; } html { /* 修复iOS点击高亮问题 */ -webkit-tap-highlight-color: transparent; /* 平滑滚动 */ scroll-behavior: smooth; } /* 防止超长内容破坏布局 */ img, picture, video, canvas, svg { display: block; max-width: 100%; }2. 排版基础重置 统一各浏览器的文本渲染表现。 body { line-height: 1.5; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; /* 改善CJK文本的显示 */ -webkit-text-size-adjust: 100%; } /* 统一标题样式 */ h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } /* 重置链接样式 */ a { color: inherit; text-decoration: none; }3. 表单元素标准化 消除表单元素的浏览器默认样式差异。 图片 4. 列表样式重置 统一列表显示效果。 图片 5. 媒体元素优化 确保媒体元素在各浏览器中的一致表现。 图片 6. 滚动条行为统一 统一各浏览器的滚动条行为。 图片 7. 触摸操作优化 优化移动设备的触摸体验。 图片 8. 打印样式优化 确保网页在打印时的正确显示。 @media print { /* 打印时的颜色和背景处理 */ * { -webkit-print-color-adjust: exact; print-color-adjust: exact; color-adjust: exact; } /* 避免打印时断页问题 */ a { page-break-inside: avoid; } /* 确保打印时显示完整的URL */ a[href^="http"]::after { content: " (" attr(href) ")"; } }欢迎补充。
-
一个浏览器就能拥有一个完整操作系统 简介 互联网操作系统 Puter 是一个先进的开源桌面环境,它运行在浏览器中,并具备丰富的功能、异常快速以及高度可扩展性。 它是一个功能丰富、快速且可扩展的开源桌面环境,提供了多种应用场景和便利工具,满足用户在不同场景下的需求。 主要特征 远程桌面环境:允许用户从任何地方访问桌面环境进行工作、娱乐等操作 云存储服务:所有文件可保存在安全的地方并随时随地访问 Web 托管平台:支持构建和托管网站、Web 应用程序和游戏 替代传统云盘:提供清新界面和强大功能替代 Dropbox/Google Drive 等 应用场景 个人使用:作为个人云盘随时随地访问管理文件 企业应用:构建远程工作桌面提供便捷环境 开发者工具:用于构建和托管网站/应用/游戏 技术特点 隐私至上:用户数据和隐私充分保护 跨平台兼容:基于 Web 技术可在多平台运行 高度可扩展:支持根据需求定制系统 友好社区:提供学习 Web 开发/云计算等知识的开源社区 GitHub 地址:隐藏内容,请前往内页查看详情 官方网站:隐藏内容,请前往内页查看详情 官方文档:隐藏内容,请前往内页查看详情安装部署 Docker 部署流程: 安装 Docker sudo apt update sudo apt install -y docker.io docker-compose 拉取镜像 sudo docker pull ghcr.io/heyputer/puter 启动服务 sudo docker run --rm -p 4100:4100 \ -v `pwd`/puter/config:/etc/puter \ -v `pwd`/puter/data:/var/puter \ ghcr.io/heyputer/puter 访问地址:http://[IP]:4100 图片 图片 图片
-
少数人知道的 10 个神奇 CSS 选择器 在 Web 开发中,CSS 扮演着至关重要的角色,但很多开发者并没有真正发掘它的全部潜力! 大多数人熟悉 ID 选择器、类选择器或元素选择器,甚至伪元素的使用也很常见。然而,你知道 CSS 其实还有许多不为人知的强大选择器吗? 今天,就带你揭秘一些鲜有人知但却非常实用的 CSS 选择器,让你在样式控制上更上一层楼! 图片 1. 属性选择器 属性选择器可以根据 HTML 元素的属性来应用样式,而无需额外添加类或 ID。 基础属性选择器 a[href] { color: blue; }这个选择器会为所有包含 href 属性的 <a> 元素添加蓝色字体样式。 指定属性值的选择器 input[type="text"] { border: 1px solid #ccc; }此规则仅作用于 type="text" 的输入框。 匹配部分属性值的选择器 /* 以某个值开头(^=) */ a[href^="https"] { color: green; } /* 以某个值结尾($=) */ a[href$=".pdf"] { color: red; } /* 包含某个值(*=) */ a[href*="example"] { color: orange; }这些选择器可以分别选中以 https 开头的链接、以 .pdf 结尾的链接,以及包含 example 关键字的链接,并应用不同的样式。 2. :nth-child() 选择器 该伪类选择器可以基于元素在其父元素中的位置来应用样式: li:nth-child(odd) { background-color: #f9f9f9; }这将使奇数序号的 <li> 元素具有不同的背景颜色。 3. :not() 选择器 想要排除某些特定元素?:not() 选择器可以帮你实现: button:not(.primary) { background-color: grey; }以上代码会为所有 不 具有 .primary 类的 <button> 按钮应用灰色背景。 4. :focus 选择器 提升用户体验和可访问性的一种方式是给获取焦点的元素添加样式: input:focus { outline: 2px solid blue; }当输入框获得焦点时,会显示一个蓝色的外边框。 5. ::before 和 ::after 伪元素 这两个伪元素可以在某个元素的前后插入内容,无需修改 HTML 结构: h1::before { content: "§ "; color: grey; } p::after { content: " (阅读更多)"; color: blue; }上面的示例会在所有 <h1> 标题前添加灰色的 "§ " 符号,并在每个 <p> 段落后面附加 "(阅读更多)" 的蓝色文本。 6. ::first-line 选择器 想让段落的首行样式有所不同?可以这样做: p::first-line { font-weight: bold; color: red; }这会让段落的首行变成 加粗 且 红色。 7. ::first-letter 选择器 如果你想让段落的首字母更具视觉吸引力,可以使用 ::first-letter: p::first-letter { font-size: 2em; color: green; }这样,所有段落的第一个字母都会被放大,并且颜色变成绿色。 8. :empty 选择器 这个选择器可以选中 没有子元素(包括文本内容)的 HTML 元素: div:empty { border: 1px dashed red; }这样,所有空的 <div> 元素都会带有红色虚线边框。 9. :checked 选择器 专门用于选中 复选框(checkbox) 或 单选按钮(radio) 的样式控制: input[type="checkbox"]:checked + label { font-weight: bold; }当复选框被选中时,相关的 <label> 标签会变成加粗字体。 10. 组合选择器 CSS 选择器可以组合使用,以实现更精准的样式控制。例如: a[href^="https"]:not([href*="example"])::after { content: " (安全)"; color: green; }这个规则会为 以 https 开头且不包含 "example" 关键字 的链接,在其后面添加绿色的 "(安全)" 标识。 结语 希望这篇文章能帮助你更好地理解 CSS 选择器的强大之处。如果你有什么喜欢的 CSS 选择器,欢迎在评论区分享!
-
删除 node_modules 目录太慢了?教你快速删除 前言 大家好,我是易航,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~ 在开发过程中,node_modules 文件夹常常会因为存放了大量的依赖包而变得庞大,尤其是在大型项目中。虽然 node_modules 是 Node.js 项目中不可或缺的一部分,但在一些特定的情况下,比如清理无用依赖或是重新安装依赖时,删除 node_modules 文件夹是一个常见的操作。然而,手动删除这么大的文件夹往往是一个耗时且效率低下的过程。对于开发者而言,如何快速有效地删除 node_modules 成为了一个常见的痛点。 这时,rimraf 工具就显得尤为重要,它可以替代rm -rf命令来递归删除文件夹,并且相较于手动删除,它提供了更高效的方式。 一、什么是 rimraf? rimraf 是一个 Node.js 库,用于递归地删除文件和目录,特别适用于删除 node_modules 这样的庞大文件夹。rimraf 在删除文件和文件夹时,采用了优化过的实现,特别能够提高大文件夹删除的效率。 与操作系统自带的 rm -rf 命令相比,rimraf 通过减少系统调用、避免进程挂起等方式,能够加快删除过程,尤其在 Windows 平台上表现尤为突出,因为 Windows 本身对于删除大量文件的支持不如类 Unix 系统。 二、为什么手动删除 node_modules 这么慢? 在大型 Node.js 项目中,node_modules 文件夹可能包含上万个文件和子文件夹。由于 node_modules 文件夹结构的复杂性和深度,手动删除该文件夹需要操作系统一次性处理大量的文件删除操作。在这种情况下,操作系统的文件系统(如 macOS 的 HFS+ 或 Windows 的 NTFS)可能会出现延迟,导致删除过程非常缓慢。 图片 1. 操作系统的文件系统限制 操作系统的文件系统并没有针对大规模删除优化。例如,当你使用文件资源管理器删除文件时,它实际上是逐一标记每个文件为删除状态,并且还会消耗大量的资源来更新文件索引。这对于 node_modules 这种成千上万个文件的文件夹来说,执行起来非常低效。 2. 文件系统缓存和索引 文件操作系统通常会保持一定的缓存和索引记录,以便加速文件的读写和删除过程。然而,当需要删除大量文件时,这些缓存和索引会成为瓶颈,导致删除变得缓慢。 三、如何使用 rimraf 加速删除过程? rimraf 是一个专为递归删除大文件夹设计的工具,它通过优化删除过程中的一些细节,避免了文件系统缓存和索引的限制,使得删除过程更加高效。使用 rimraf 删除 node_modules 的步骤非常简单,以下是详细的操作流程。 1. 安装 rimraf 首先,我们需要在项目中安装 rimraf。可以通过 npm 或 yarn 来安装它。打开你的命令行,进入到你的项目目录下,执行以下命令: npm install rimraf --save-dev或者使用 yarn: yarn add rimraf --dev2. 在命令行中使用 rimraf 安装完成后,你可以在命令行中直接使用 rimraf 来删除 node_modules 文件夹。以下是使用 rimraf 删除 node_modules 的命令: npx rimraf node_modules3. 在 package.json 中配置脚本 为了简化操作,可以将删除命令添加到 package.json 中的 scripts 部分: { "scripts": { "clean": "rimraf node_modules" } }然后运行: npm run clean4. 使用 rimraf 加速其他删除操作 除了删除 node_modules,rimraf 还可以删除其他大文件夹: npx rimraf build四、rimraf 的优势 跨平台兼容:支持 Linux、macOS 和 Windows。 高效删除:针对大规模文件删除优化,速度显著提升。 易于使用:通过命令行或脚本配置即可快速操作。 与包管理工具集成:无缝配合 npm、yarn 使用。 五、总结 rimraf 是一个轻量级、高效且跨平台的工具,特别适合快速删除 node_modules 等大型文件夹。通过优化删除流程,它能显著提升开发效率,尤其是在 Windows 系统上表现突出。如果你还在手动删除 node_modules,不妨尝试使用 rimraf 来简化工作流程。 结语 我是易航,待过多种类型公司的前端开发者,始终坚持用通俗易懂的方式分享技术知识。欢迎关注我的博客「易航博客」获取更多前端干货!
-
使用 HTML、CSS 和 JavaScript 构建简易屏幕录像机 欢迎各位参与这个简单易行的屏幕录像项目!我们将仅使用传统的 HTML、CSS 和 JavaScript 共同完成。您可能会疑惑:为何需要这样的工具?答案在于屏幕录制对教程制作、演示汇报、缺陷报告等诸多场景至关重要。无论您是为频道创建分步教学视频,还是向潜在客户展示作品集,这类应用都不可或缺。本文将带您打造一款简约却强大的屏幕录像工具,完全基于 HTML、CSS 和 JavaScript 实现。 工具准备 如先前所述,本项目无需任何第三方库。但若您零编码经验,建议先观看此教程学习代码编辑器基础。 项目目标 本工具支持用户直接通过浏览器录制屏幕画面及完整音频。点击录制按钮后,系统将提示选择录制区域(如 Chrome 标签页),支持多窗口选择或全屏录制。右下角的 "同时共享音频" 选项可自由开关。录制前设有倒计时,最终视频以 WebM 格式下载。 代码轻量无依赖,充分利用浏览器原生 API。让我们深入解析: 架构分解 HTML 构建界面:包含视频预览、录制按钮和下载链接 CSS 样式设计:响应式布局与动感倒计时层 JavaScript 核心功能:屏幕捕捉、视频录制与下载逻辑 现在让我们深入代码实现。 HTML 结构 创建 index.html 文件,编写基础界面代码(有经验者可自定义调整): <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <script src="script.js" defer></script> <title>在线屏幕录制</title> </head> <body> <div class="countdown" id="countdown"></div> <div class="screen-recorder"> <h1>开启屏幕录制</h1> <video controls preload="none" id="video"></video> <nav> <button type="button" class="btn" id="btn" aria-label="开始录制">录制</button> <a href="#" class="btn" id="link" aria-label="下载录制视频" download="recording.webm">下载视频</a> </nav> </div> </body> </html>video 元素展示录制内容,button 和 a 分别控制录制与下载。 CSS 样式 创建 style.css 美化界面(CSS 新手可参考 W3School 教程): 关键样式说明: 全局重置:统一边距与盒模型 居中布局:使用网格布局实现垂直水平居中 倒计时层:全屏半透明遮罩与大号数字显示 响应式视频:自适应屏幕尺寸 按钮设计:统一风格与悬停效果 移动适配:媒体查询优化小屏体验 * { padding: 0; margin: 0; box-sizing: border-box; } body { width: 100vw; min-height: 100vh; display: grid; place-items: center; background-color: #f4f4f4; } .countdown { visibility: hidden; color: green; font-size: 10rem; font-weight: 900; background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色背景 */ position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; display: flex; align-items: center; justify-content: center; } .screen-recorder { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2rem; width: 90%; max-width: 1000px; padding: 2rem; background-color: #fff; color: #202020; border-radius: 10px; box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2); } .screen-recorder video { width: 100%; max-width: 782px; aspect-ratio: 16 / 9; max-height: 440px; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1), -2px -2px 5px rgba(0, 0, 0, 0.1); border-radius: 10px; display: none; } h1 { text-transform: capitalize; font-size: 3rem; font-weight: bold; color: #202020; } .btn { background-color: #428bca; color: #fff; font-weight: 900; padding: 0.75rem 1.5rem; border-radius: 0.5rem; cursor: pointer; text-transform: capitalize; border: 1px solid #428bca; transition: background-color 0.3s ease, color 0.3s ease; } .btn:hover, .btn:focus { background-color: #357ec7; outline: 2px solid #357ec7; outline-offset: 2px; } a { text-decoration: none; margin-inline-start: 20px; display: none; } @media (max-width: 768px) { .screen-recorder video { width: 100%; height: auto; } h1 { font-size: 2.5rem; } .btn { padding: 0.5rem 1rem; font-size: 1rem; } .countdown { font-size: 6rem; } }JavaScript 功能 创建 script.js 实现核心逻辑: 隐藏内容,请前往内页查看详情 功能解析 事件驱动:按钮点击触发录制流程 媒体捕获:使用 getDisplayMedia 获取屏幕流,getUserMedia 获取音频 倒计时机制:Promise 实现 3 秒倒计时 录制控制:MediaRecorder API 处理视频流 下载生成:Blob 对象转换下载链接 常见问题解答 Q: 能否录制系统音频? A: 受浏览器安全策略限制,系统音频录制可能存在限制,建议使用麦克风输入。 Q: 无法录屏的解决办法? A: 确保浏览器支持 getDisplayMedia API,最新版 Chrome/Firefox 均可。 Q: 如何提升音质? A: 代码已启用回声消除与降噪,建议外接优质麦克风。 Q: 支持暂停录制吗? A: 当前版本未实现,可停止后重新开始。 优劣分析 优势局限无依赖轻量级仅支持现代浏览器简单易实现无高级编辑功能音视频同步录制音频设备兼容性问题Webm 格式下载需转换格式兼容播放响应式设计无实时预览功能通过本文,您已掌握构建基础屏幕录像工具的全流程。现在即可动手实践,打造专属的录屏解决方案! 演示站:http://web.bri6.cn/tool/screen-record/ 图片
-
JavaScript 意外的副作用:修改共享变量 由于闭包可以访问外部函数的变量,如果不小心修改了这些变量,可能会导致意想不到的副作用。 function outer() { let counter = 0; return { increment: function() { counter++; }, getCount: function() { return counter; } }; } const myCounter = outer(); myCounter.increment(); myCounter.increment(); console.log(myCounter.getCount()); // 输出 2在这个例子中, 虽然我们希望 counter 变量是 outer 函数的私有变量, 但是通过闭包, 我们仍然可以在外部修改它. 解决方法: 最小化共享: 尽量减少闭包对外部变量的修改,优先使用局部变量。 使用不可变数据: 如果外部变量是对象或数组,尽量使用不可变数据结构,避免意外修改。 更明确的接口: 如果确实需要修改, 那么就通过定义明确的接口来修改。 图片
-
JavaScript 循环中的闭包陷阱:“意料之外” 的共享 闭包 (Closure) 无疑是 JavaScript 中最强大、最迷人的特性之一。它赋予了函数访问其定义时所在词法环境的能力,即使该函数在其定义的作用域之外执行。凭借闭包,我们可以实现数据封装、模块化、柯里化等高级编程技巧。 然而,硬币的另一面是,闭包也常常被视为 JavaScript 中最容易误解、最容易出错的特性之一。稍有不慎,就会掉入闭包的“陷阱”,导致内存泄漏、意外的变量共享等问题。 图片 在循环中使用闭包时,很容易出现意外的变量共享问题。 图片 在这个例子中,我们期望 setTimeout 的回调函数(闭包)分别输出 0, 1, 2, 3, 4。但实际输出的却是 5 次 5。这是因为 setTimeout 是异步执行的,当回调函数执行时,循环已经结束,i 的值已经变成了 5。而且,由于使用了 var 声明 i,所有的回调函数共享的是同一个 i 变量。 解决方法: 使用 let 声明循环变量:let 具有块级作用域,每次循环都会创建一个新的 i 变量,避免了变量共享。 图片 使用立即执行函数 (IIFE):创建一个立即执行函数,将循环变量 i 作为参数传递进去,形成一个闭包,每次循环都会创建一个新的作用域。 图片 使用bind方法:使用 bind 方法将循环变量 i 绑定到回调函数上。 图片
-
JavaScript 内存泄漏:“永不消逝” 的变量 闭包最常见的陷阱就是内存泄漏。当一个闭包引用了外部函数的变量,而这个闭包又被长期持有(例如,作为事件处理程序或定时器回调),那么外部函数的变量就无法被垃圾回收,导致内存泄漏。 function createHandler() { let largeObject = new Array(1000000).fill("data"); // 创建一个大对象 return function() { console.log("Handler clicked"); // 没有直接使用 largeObject, 但由于闭包的存在, largeObject 无法被回收 }; } document.getElementById("myButton").addEventListener("click", createHandler());在这个例子中,createHandler 函数返回一个事件处理函数(闭包)。这个闭包引用了 createHandler 函数的 largeObject 变量。即使我们没有在事件处理函数中直接使用 largeObject,但由于闭包的存在,largeObject 无法被垃圾回收,导致内存泄漏。 解决方法: 解除引用:在不需要闭包时,手动解除对闭包的引用,例如: let handler = createHandler(); document.getElementById("myButton").addEventListener("click", handler); // ... 当不再需要事件处理程序时 ... document.getElementById("myButton").removeEventListener("click", handler); handler = null; // 解除对闭包的引用避免不必要的闭包:如果不需要访问外部函数的变量,就不要创建闭包。 将变量设置为null: 在闭包中, 将不再需要的外部变量手动设置为null。 图片
-
16 个 JavaScript 简写神技,代码效率提升 60%! JavaScript 是一门强大且灵活的语言,拥有丰富的特性和语法糖。分享下 16 个最常用的 JavaScript 的简写技巧,掌握它们可以让我们编写出更简洁、更优雅的代码,并显著提升开发效率(增加摸鱼时间)。 图片 1. 三元运算符简化条件判断 // 传统写法 let result; if (someCondition) { result = 'yes'; } else { result = 'no'; } // 简写方式 const result = someCondition ? 'yes' : 'no';2. 空值合并运算符 // 传统写法 const name = user.name !== null && user.name !== undefined ? user.name : 'default'; // 简写方式 const name = user.name ?? 'default';3. 可选链操作符 // 传统写法 const street = user && user.address && user.address.street; // 简写方式 const street = user?.address?.street;4. 数组去重 // 传统写法 function unique(arr) { return arr.filter((item, index) => arr.indexOf(item) === index); } // 简写方式 const unique = arr => [...new Set(arr)];5. 快速取整 // 传统写法 const floor = Math.floor(4.9); // 简写方式 const floor = ~~4.9;6. 合并对象 // 传统写法 const merged = Object.assign({}, obj1, obj2); // 简写方式 const merged = {...obj1, ...obj2};7. 短路求值 // 传统写法 if (condition) { doSomething(); } // 简写方式 condition && doSomething();8. 默认参数值 // 传统写法 function greet(name) { name = name || 'Guest'; console.log(`Hello ${name}`); } // 简写方式 const greet = (name = 'Guest') => console.log(`Hello ${name}`);9. 解构赋值 图片 10. 字符串转数字 图片 11. 多重条件判断 图片 12. 快速幂运算 图片 13. 对象属性简写 图片 14. 数组映射 图片 15. 交换变量值 图片 16. 动态对象属性 // 传统写法 const obj = {}; obj[dynamic + 'name'] = value; // 简写方式 const obj = { [`${dynamic}name`]: value };欢迎补充。