前端开发技术
前端开发技术 #
前端开发基础知识、jQuery选择器、框架对比、面试要点
📋 目录 #
jQuery选择器大全 #
基本选择器 #
| 选择器 | 说明 |
|---|---|
$("#myElement") |
选择id等于myElement的元素(唯一) |
$("div") |
选择所有的div标签元素,返回div元素数组 |
$(".myClass") |
选择使用myClass类的css的所有元素 |
$("*") |
选择文档中的所有元素 |
联合选择示例:
$("#myELement,div,.myclass")
层级选择器 #
| 选择器 | 说明 |
|---|---|
$("form input") |
选择所有的form元素中的input元素 |
$("#main > *") |
选择id值为main的所有的直接子元素 |
$("label + input") |
选择所有label元素后面直接跟的input元素 |
$("#prev ~ div") |
选择id为prev的标签元素的所有同胞div元素 |
过滤选择器 #
| 选择器 | 说明 |
|---|---|
$("tr:first") |
选择所有tr元素的第一个 |
$("tr:last") |
选择所有tr元素的最后一个 |
$("input:not(:checked) + span") |
过滤掉checked状态的input后,选择相邻的span |
$("tr:even") |
选择所有tr元素中序号为偶数的元素(序号从0开始) |
$("tr:odd") |
选择所有tr元素中序号为奇数的元素 |
$("td:eq(2)") |
选择所有td元素中序号为2的那个td元素 |
$("td:gt(4)") |
选择td元素中序号大于4的所有td元素 |
$("td:lt(4)") |
选择td元素中序号小于4的所有的td元素 |
$(":header") |
选择所有标题元素 (h1-h6) |
$("div:animated") |
选择所有正在执行动画的div元素 |
内容过滤选择器 #
| 选择器 | 说明 |
|---|---|
$("div:contains('John')") |
选择所有div中含有John文本的元素 |
$("td:empty") |
选择所有的为空(也不包括文本节点)的td元素 |
$("div:has(p)") |
选择所有含有p标签的div元素 |
$("td:parent") |
选择所有以td作为父节点的元素 |
可见性过滤选择器 #
| 选择器 | 说明 |
|---|---|
$("div:hidden") |
选择所有的被hidden的div元素 |
$("div:visible") |
选择所有的可视化的div元素 |
属性过滤选择器 #
| 选择器 | 说明 |
|---|---|
$("div[id]") |
选择所有含有id属性的div元素 |
$("input[name='newsletter']") |
选择所有的name属性等于'newsletter'的input元素 |
$("input[name!='newsletter']") |
选择所有的name属性不等于'newsletter'的input元素 |
$("input[name^='news']") |
选择所有的name属性以'news'开头的input元素 |
$("input[name$='news']") |
选择所有的name属性以'news'结尾的input元素 |
$("input[name*='man']") |
选择所有的name属性包含'man'的input元素 |
$("input[id][name$='man']") |
多条件过滤:含有id属性且name以man结尾 |
子元素过滤选择器 #
| 选择器 | 说明 |
|---|---|
$("ul li:nth-child(2)") |
选择每个ul下的第2个子元素li |
$("ul li:nth-child(odd)") |
选择每个ul下的奇数位置li |
$("ul li:nth-child(3n + 1)") |
选择每个ul下位置符合 3n+1 的li |
$("div span:first-child") |
返回所有的div元素的第一个子节点span |
$("div span:last-child") |
返回所有的div元素的最后一个节点span |
$("div button:only-child") |
返回所有的div中只有唯一一个子节点的button |
表单对象选择器 #
| 选择器 | 说明 |
|---|---|
$(":input") |
选择所有的表单输入元素,包括input, textarea, select 和 button |
$(":text") |
选择所有的text input元素 |
$(":password") |
选择所有的password input元素 |
$(":radio") |
选择所有的radio input元素 |
$(":checkbox") |
选择所有的checkbox input元素 |
$(":submit") |
选择所有的submit input元素 |
$(":image") |
选择所有的image input元素 |
$(":reset") |
选择所有的reset input元素 |
$(":button") |
选择所有的button input元素 |
$(":file") |
选择所有的file input元素 |
$(":hidden") |
选择所有类型为hidden的input元素或表单的隐藏域 |
表单对象属性过滤选择器 #
| 选择器 | 说明 |
|---|---|
$(":enabled") |
选择所有的可操作的表单元素 |
$(":disabled") |
选择所有的不可操作的表单元素 |
$(":checked") |
选择所有的被checked的表单元素 |
$("select option:selected") |
选择所有的select中被选中的option元素 |
常见用法示例 #
// 选取一个 name 为"S_03_22"的input text框的上一个td的text值
$("input[name =S_03_22]").parent().prev().text()
// 名字以"S_"开始,并且不是以"_R"结尾
$("input[name ^='S_']").not("[name $='_R']")
// 获取一个名为 radio_01的radio所选的值
$("input[name =radio_01][checked]").val()
层级选择器对比:
| 语法 | 说明 |
|---|---|
$("A B") |
查找A元素下面的所有子节点,包括非直接子节点 |
$("A>B") |
查找A元素下面的直接子节点 |
$("A+B") |
查找A元素后面的兄弟节点,包括非直接子节点 |
$("A~B") |
查找A元素后面的兄弟节点,不包括非直接子节点 |
批量抓取示例:
// 抓取页面所有链接
var items = $("div.list-content div.course-link a");
for(var i = 0; i < items.length; i++) {
console.log(items[i].href);
}
前端框架对比 #
主流框架对比 #
| 框架 | 公司/作者 | 特点 | 适用场景 | 推荐度 |
|---|---|---|---|---|
| React | Meta | 组件化、JSX、虚拟DOM | 大型应用、单页应用 | ⭐⭐⭐⭐⭐ |
| Vue | 尤雨溪 | 渐进式、易学、双向绑定 | 中大型应用、快速开发 | ⭐⭐⭐⭐⭐ |
| Angular | 全功能、TypeScript | 企业级大型应用 | ⭐⭐⭐⭐ | |
| Svelte | Rich Harris | 编译时框架、无虚拟DOM | 现代应用、性能优先 | ⭐⭐⭐⭐ |
CSS框架对比 #
| 框架 | 特点 | 推荐场景 | 推荐度 |
|---|---|---|---|
| Tailwind CSS | 原子化CSS、灵活 | 现代项目、快速开发 | ⭐⭐⭐⭐⭐ |
| Bootstrap | 传统UI框架、预制组件 | 快速原型开发 | ⭐⭐⭐⭐ |
| Ant Design | React企业级UI组件库 | 中后台系统 | ⭐⭐⭐⭐⭐ |
| Element UI | Vue企业级UI组件库 | 中后台系统 | ⭐⭐⭐⭐⭐ |
面试题汇总 #
基础篇 #
- CSS选择器优先级有哪些?
- 什么是盒子模型?标准盒模型 vs IE怪异盒模型?
- 什么是回流(reflow)和重绘(repaint)?如何优化?
- 如何实现垂直水平居中?
- JS中闭包是什么?有什么作用?
框架篇 #
- Vue和React的区别?
- Virtual DOM的原理是什么?
- 什么是组件化开发?
- Vue的响应式原理是什么?
- React Hooks解决了什么问题?
性能优化篇 #
- 前端性能优化有哪些常用方法?
- 如何减少HTTP请求?
- 图片懒加载原理是什么?
- 什么是防抖和节流?应用场景?
- 如何优化首屏加载速度?
面试题答案详解 #
基础篇 #
- CSS选择器优先级有哪些?
答案:
优先级从高到低:
- !important:最高优先级(慎用)
- 内联样式:style="..."
- ID选择器:#id
- 类选择器/属性选择器/伪类:.class / [attr] / :hover
- 标签选择器/伪元素:div / ::before
计算规则:
- 选择器越具体,优先级越高
- 相同优先级,后面的覆盖前面的
- 继承来的样式优先级最低
示例:
/* 优先级:内联 > ID > 类 > 标签 */
<div id="box" class="content" style="color: red">
<p>Hello</p>
</div>
#box { color: blue; } /* 优先级高于类 */
.content { color: green; }
- 什么是盒子模型?标准盒模型 vs IE怪异盒模型?
答案:
盒子模型: 每个元素由:
- content:内容区
- padding:内边距
- border:边框
- margin:外边距
标准盒模型(content-box):
- width/height只包含content
- 总宽 = content + padding + border
IE怪异盒模型(border-box):
- width/height包含content + padding + border
- 总宽 = width
CSS控制:
/* 标准盒模型 */
box-sizing: content-box;
/* IE盒模型(推荐) */
box-sizing: border-box;
- 什么是回流(reflow)和重绘(repaint)?如何优化?
答案:
重绘(Repaint):
- 元素外观改变(颜色、背景),不影响布局
- 只重新绘制,性能开销较小
回流(Reflow):
- 元素尺寸、位置、布局改变
- 需要重新计算布局,性能开销大
- 回流必然导致重绘
如何优化:
- 减少DOM操作:批量修改
- 使用文档片段:DocumentFragment
- 脱离文档流:position: absolute/fixed
- 避免频繁访问布局属性:offsetWidth、clientWidth等
- 使用transform代替top/left:不会触发回流
- 启用GPU加速:transform: translateZ(0)
- 如何实现垂直水平居中?
答案:
方法1:Flex(推荐)
.parent {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
方法2:Grid
.parent {
display: grid;
place-items: center; /* 简写 */
}
方法3:绝对定位 + margin
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
方法4:绝对定位 + margin: auto
.child {
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
margin: auto;
}
方法5:表格布局
.parent {
display: table-cell;
text-align: center;
vertical-align: middle;
}
- JS中闭包是什么?有什么作用?
答案:
闭包:
- 函数可以访问外部作用域的变量,即使外部函数已执行完
- 变量会被保留,不会被垃圾回收
例子:
function makeCounter() {
let count = 0;
return function() {
return ++count; // 访问外部变量count
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
counter(); // 3
作用:
- 数据私有化:隐藏变量,只暴露方法
- 函数工厂:创建类似但独立的函数
- 模块化:模拟私有属性
框架篇 #
- Vue和React的区别?
答案:
| 对比项 | Vue | React |
|---|---|---|
| 模板语法 | 模板语法(HTML-like) | JSX |
| 响应式 | 双向绑定(v-model) | 单向数据流 |
| 学习曲线 | 平缓,渐进式 | 较陡,概念多 |
| 生态 | Vue生态,Vuex/Pinia | React生态,Redux/MobX |
| 状态管理 | 内置响应式,Pinia/Vuex | 需要第三方库 |
| 企业使用 | 国内多 | 国外多 |
共同点:
- 组件化开发
- 虚拟DOM
- 单页应用框架
- Virtual DOM的原理是什么?
答案:
虚拟DOM:
- JS对象模拟真实DOM
- 变化时,对比新旧虚拟DOM(diff算法)
- 只更新变化的部分
原理:
- 创建虚拟DOM:JS表示DOM树
- Diff对比:对比新旧树差异
- Patch更新:应用差异到真实DOM
优点:
- 减少DOM操作次数
- 批量更新
- 跨平台(React Native)
示例:
// 虚拟DOM(JS对象)
const vNode = {
tag: 'div',
props: { class: 'container' },
children: [{ tag: 'p', children: 'Hello' }]
};
- 什么是组件化开发?
答案:
组件化:
- 将UI拆分为独立、可复用的组件
- 每个组件有自己的逻辑和样式
组件特点:
- 可复用:复用组件,减少重复代码
- 可维护:独立修改组件
- 解耦:组件间低耦合
示例:
// React组件
function Button(props) {
return <button className={props.className}>{props.text}</button>;
}
// 使用
<Button text="点击" className="primary" />
- Vue的响应式原理是什么?
答案:
Vue 2:
- Object.defineProperty 监听getter/setter
- 递归劫持对象属性
- 数组重写push/pop等方法
Vue 3:
- Proxy 代理对象(更强大)
- 监听对象和数组
- 懒代理,性能更好
核心机制:
- 依赖收集:getter时收集依赖(Watcher)
- 触发更新:setter时通知Watcher
- 视图更新:Watcher触发组件更新
示例:
const state = reactive({ count: 0 });
state.count = 1; // 触发更新
- React Hooks解决了什么问题?
答案:
Hooks解决的问题:
- 类组件复杂性:this、生命周期难以理解
- 状态逻辑复用:高阶组件嵌套深,render props复杂
- 组件臃肿:生命周期里逻辑混杂
常用Hooks:
// 状态管理
const [count, setCount] = useState(0);
// 副作用
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
// 自定义Hook(复用状态逻辑)
function useCounter() {
const [count, setCount] = useState(0);
return { count, increment: () => setCount(c => c + 1) };
}
性能优化篇 #
- 前端性能优化有哪些常用方法?
答案:
加载优化:
- 减少HTTP请求:合并文件、雪碧图
- 压缩资源:gzip、代码压缩
- CDN加速:静态资源放CDN
- 缓存策略:浏览器缓存、Service Worker
渲染优化:
- 减少DOM操作:虚拟DOM、批量更新
- 避免回流重绘:transform代替top/left
- 懒加载:图片、组件懒加载
- 防抖节流:优化事件处理
代码优化:
- Tree Shaking:删除未使用代码
- 代码分割:按需加载
- Web Worker:后台计算
- 如何减少HTTP请求?
答案:
方法:
- 合并文件:JS、CSS合并
- 雪碧图:小图合成一张
- Data URI:小图转为base64
- 字体图标:图标转为字体
- 减少资源:移除未使用的JS/CSS
- 缓存:设置合理的缓存策略
- HTTP2/3:多路复用
示例:
/* 雪碧图:所有小图在一张图上 */
.icon {
background-image: url(sprite.png);
}
.icon-home { background-position: 0 0; }
.icon-user { background-position: -32px 0; }
- 图片懒加载原理是什么?
答案:
原理:
- 只加载视口内的图片
- 滚动时检查元素是否进入视口
- 进入视口时替换data-src为src
原生方法(推荐):
<!-- 原生懒加载,简单高效 -->
<img src="placeholder.jpg" data-src="real.jpg" loading="lazy">
JavaScript实现:
// IntersectionObserver监听
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // 替换为真实地址
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
- 什么是防抖和节流?应用场景?
答案:
防抖(Debounce):
- 多次触发,只执行最后一次
- 应用:输入搜索、窗口resize
节流(Throttle):
- 固定时间间隔执行一次
- 应用:滚动加载、按钮点击
代码示例:
// 防抖
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
// 节流
function throttle(fn, delay) {
let last = 0;
return function(...args) {
const now = Date.now();
if (now - last > delay) {
last = now;
fn(...args);
}
};
}
// 使用
const search = debounce(queryAPI, 300);
const scroll = throttle(onScroll, 100);
- 如何优化首屏加载速度?
答案:
方法:
- 减小首屏资源体积:代码分割、Tree Shaking
- 预加载关键资源:
<link rel="preload"> - 懒加载非关键资源:路由懒加载、组件懒加载
- 优化关键渲染路径:内联关键CSS、异步加载JS
- 减少HTTP请求:合并、压缩
- CDN加速:静态资源CDN
- 服务端渲染:SSR/SSG
- PWA缓存:Service Worker
示例:
<!-- 预加载关键资源 -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="hero.jpg" as="image">
<!-- 异步加载非关键JS -->
<script src="analytics.js" async></script>
🔗 相关笔记 #
最后更新: 2026-04-29