尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
STM32裸机驱动OV2640输出JPEG流实战指南
简介本资源是一套基于STM32F407平台的OV2640图像传感器完整驱动工程面向嵌入式开发初学者与进阶工程师解决CMOS摄像头在ARM Cortex-M4芯片上的底层驱动适配、JPEG图像采集与SPI高速通信等核心问题适用于智能监控、机器人视觉、无人机图传等实际项目。压缩包共212个文件以58个C源文件和56个头文件.c/.h构成主体逻辑辅以编译中间文件.o/.d、Keil工程配置.uvprojx/.uvoptx、调试脚本.bat及映射文件.map/.axf完整呈现从硬件初始化、寄存器配置序列、DMA加速传输到JPEG数据读取的全流程实现包体大小为6.82MB。已有2569人学习下载资源结构清晰、注释充分含标准HAL库移植代码与典型分辨率QVGA/UXGA切换支持可直接编译运行于启明欣欣STM32F407开发板大幅降低OV2640驱动开发门槛与调试周期。1. OV2640驱动.zip不是“能点亮摄像头”就完事而是让STM32在无RTOS、无DMA、仅靠GPIO模拟I2C的裸机环境下稳定输出640×48015fps的JPEG流——适合做嵌入式视觉终端原型、智能小车图像采集模块、或作为毕业设计中“看得见摸得着”的图像输入底座你手头有一块STM32F103C8T6最小系统板没接WiFi模块没跑FreeRTOS甚至没外扩SDRAM但你想让摄像头动起来不是只初始化成功、读个ID就截图发朋友圈那种“点亮”而是真能把一帧640×480的JPEG数据从OV2640里完整抓出来校验不丢包、时序不粘连、连续抓100帧不卡死、内存不越界。这个OV2640驱动.zip就是为这种“硬核裸机场景”准备的——它不依赖HAL库的I2C中断回调不封装成抽象层API所有寄存器配置值都来自OV2640官方Datasheet Rev 1.42015年版关键时序用__NOP()和Delay_us()硬控JPEG数据流通过FSMC若用F103ZET6或GPIO bit-bangC8T6分段搬移每帧带CRC校验长度头。它不是教学Demo是某高校嵌入式实验室给学生做“智能巡线小车图像识别模块”时压箱底的真实工程包压缩包里没有README.md只有ov2640.c/h、scb_regs.h、jpeg_parser.c和一份手写的ov2640_reg_list.xlsx——后者列出了全部127个可写寄存器的实际用途、推荐值、修改后果比如0x3A0F0x40开自动白平衡会拖慢帧率但提升室内色准而0x50010x11关掉JPEG内部压缩则直接导致单帧超200KBC8T6根本存不下。如果你正被“摄像头初始化成功但取不到图”、“JPEG数据前半帧正常后半帧全黑”、“改了分辨率就花屏”这类问题卡住三天这个包就是你的后悔药。2. 硬件与协议栈解耦OV2640不是“即插即用”它的寄存器配置链必须按严格顺序执行且每步都需确认状态位OV2640本质是一颗高度集成的SoC级图像传感器内部含ADC、ISP、JPEG编码器、PLL、SCCB总线控制器。它不接受“一次性初始化”而要求主控按精确阶段推进配置流程——跳过任一阶段或顺序错乱都会导致后续JPEG流输出异常如YUV数据错位、JPEG头损坏、帧率骤降。本驱动将整个流程拆解为5个不可逆阶段每个阶段对应一组寄存器写入状态轮询全部实现在ov2640_init_sequence()函数中。2.1 阶段0上电复位与SCCB通信建立必须用软件模拟I2COV2640的SCCB接口兼容I2C但非标准对时序极其敏感SCL低电平时间需≥5μs高电平≥4μs起始信号建立时间≥4.7μs。STM32F103C8T6无硬件SCCB外设必须用GPIO模拟。驱动采用“精准延时状态反馈”双保险策略// ov2640_i2c.c void ov2640_sccb_start(void) { GPIO_SetBits(GPIOB, GPIO_Pin_6); // SCL high Delay_us(5); GPIO_SetBits(GPIOB, GPIO_Pin_7); // SDA high Delay_us(5); GPIO_ResetBits(GPIOB, GPIO_Pin_7); // SDA low (start condition) Delay_us(5); GPIO_ResetBits(GPIOB, GPIO_Pin_6); // SCL low Delay_us(5); }提示Delay_us()不是SysTick粗略延时而是基于SysTick-LOAD 72 - 172MHz主频下1μs的循环计数误差±0.2μs。若用HAL_Delay()或普通for循环SCCB通信必失败。2.2 阶段1基础寄存器预置0x12~0x36决定传感器工作模式此阶段写入32个寄存器核心是设置时钟分频、输出格式、PCLK极性。关键参数如下表均来自ov2640_reg_list.xlsx第12行标注寄存器地址推荐值作用说明修改风险0x110x01使能PLL倍频至24MHz设为0x00则PCLK12MHzJPEG编码失败0x120x80复位所有寄存器写入后需延时10ms必须第一步执行否则旧配置残留0x3a0x04PCLK下降沿采样匹配STM32 GPIO读取时机设为0x00则数据错位出现垂直条纹该阶段所有写操作后必须调用ov2640_sccb_wait_ack()检测从机应答失败则重试3次后报错OV2640_ERR_SCCB_NACK。2.3 阶段2图像尺寸与JPEG参数配置0x40~0x5a决定输出质量OV2640的JPEG压缩由内部DSP完成主控只需配置目标分辨率、质量等级、YUV采样方式。驱动默认设为640×48015fps对应寄存器组合// ov2640.c 中 ov2640_set_jpeg_size() 函数节选 ov2640_write_reg(0x44, 0x00); // HSTART low byte: 0x0000 ov2640_write_reg(0x45, 0x00); // HSTART high byte ov2640_write_reg(0x46, 0x02); // HSIZE low byte: 640 → 0x0280 ov2640_write_reg(0x47, 0x80); // HSIZE high byte ov2640_write_reg(0x48, 0x00); // VSTART low byte ov2640_write_reg(0x49, 0x00); // VSTART high byte ov2640_write_reg(0x4A, 0x01); // VSIZE low byte: 480 → 0x01E0 ov2640_write_reg(0x4B, 0xE0); // VSIZE high byte ov2640_write_reg(0x50, 0x3F); // JPEG quality: 0x00best, 0x3Ffastest注意0x50质量值非线性——0x00~0x10为无损近似0x11~0x2F为视觉无损0x30~0x3F压缩比激增但出现块效应。实测0x28为C8T6内存与画质平衡点。2.4 阶段3自动功能使能0x60~0x7f影响实时性与功耗此阶段开启AWB自动白平衡、AEC自动曝光、AGC自动增益但必须关闭AECE自动曝光控制扩展否则在低光下帧率暴跌至2fpsov2640_write_reg(0x6A, 0x00); // AWB enable ov2640_write_reg(0x6B, 0x00); // AEC enable ov2640_write_reg(0x6C, 0x00); // AGC enable ov2640_write_reg(0x7F, 0x00); // AECE disable ← 关键文档未明说但实测必设2.5 阶段4JPEG流启动与同步0x0D~0x0F触发数据输出最后三步才是真正的“开始出图”0x0D 0x00清空内部FIFO0x0E 0x80使能JPEG数据输出PCLK开始翻转0x0F 0x00设置数据格式为JPEG非YUV此时OV2640进入“流模式”PCLK引脚持续输出时钟每来一个PCLK上升沿D0~D7即更新一个字节JPEG数据。驱动通过GPIO_ReadInputDataBit()在PCLK上升沿捕获数据存入环形缓冲区。3. JPEG数据流捕获不用DMA也能稳抓640×480靠的是“双缓冲帧头校验超时熔断”OV2640输出JPEG流时数据以0xFFD8SOI开头0xFFD9EOI结尾中间夹杂0xFFxx标记码和熵编码数据。裸机环境下无法依赖DMA自动搬运驱动采用“状态机轮询校验”三重机制保障数据完整性。3.1 数据捕获状态机设计jpeg_capture_fsm()函数实现四状态循环状态触发条件动作超时处理JPEG_IDLE检测到PCLK上升沿且0xFFD8未出现进入JPEG_HEADER无JPEG_HEADER连续读取2字节0xFFD8进入JPEG_BODY重置帧长计数器500μs未捕获到SOI则重启JPEG_BODYPCLK上升沿到来存入jpeg_buf[write_ptr]frame_len单帧超180KB强制截断并报错JPEG_TAIL读取到0xFFD9且frame_len1024标记frame_ready1切换缓冲区未检测到EOI则丢弃整帧// jpeg_parser.c 关键状态转移逻辑 if (state JPEG_BODY last_byte 0xFF current_byte 0xD9) { jpeg_buf[write_ptr] 0xFF; jpeg_buf[write_ptr] 0xD9; frame_len 2; if (frame_len JPEG_MAX_SIZE) { frame_status JPEG_ERR_OVERFLOW; goto reset_frame; } state JPEG_TAIL; frame_ready 1; }3.2 双缓冲机制避免数据覆盖驱动定义两个JPEG缓冲区jpeg_buf_a[180*1024]和jpeg_buf_b[180*1024]通过buf_switch_flag切换uint8_t *jpeg_get_current_buffer(void) { return (buf_switch_flag 0) ? jpeg_buf_a : jpeg_buf_b; } void jpeg_switch_buffer(void) { buf_switch_flag !buf_switch_flag; write_ptr 0; frame_len 0; state JPEG_IDLE; }当frame_ready1时用户线程可安全读取另一缓冲区数据而新帧继续写入当前缓冲区——彻底规避“正在读取时被覆盖”的经典裸机坑。3.3 帧头校验与长度验证每帧JPEG数据入库前执行双重校验// 校验1SOI/EOI存在性 if (jpeg_buf[0] ! 0xFF || jpeg_buf[1] ! 0xD8) { return JPEG_ERR_NO_SOI; } if (jpeg_buf[frame_len-2] ! 0xFF || jpeg_buf[frame_len-1] ! 0xD9) { return JPEG_ERR_NO_EOI; } // 校验2长度合理性640×480Q28实测120~165KB if (frame_len 100*1024 || frame_len 170*1024) { return JPEG_ERR_INVALID_LEN; }提示校验失败不直接报错而是记录jpeg_err_count连续3次失败则触发ov2640_hard_reset()——重新执行全部5阶段初始化这是应对传感器偶发锁死的最有效手段。3.4 PCLK同步捕获的玄学细节OV2640的PCLK频率≈12MHz640×480模式STM32F103C8T6需在PCLK上升沿精确采样D0~D7。驱动采用“延迟补偿法”// 在PCLK上升沿后延迟150ns再读取经示波器实测最佳点 GPIO_ResetBits(GPIOA, GPIO_Pin_0); // PCLK pin Delay_ns(150); // 精确150纳秒延时 data_byte GPIO_ReadInputData(GPIOC) 0xFF; // D0~D7接PC0~PC7Delay_ns(150)由__ASM volatile (mov r0,#150\n\t subs r0,r0,#1\n\t bne .-6)实现避免编译器优化干扰。3.5 内存布局与栈空间预警C8T6仅有20KB SRAM驱动内存分配如下双JPEG缓冲区2×180KB →超出故实际使用动态分配改为jpeg_buf_a静态分配32KBjpeg_buf_b静态分配32KB超长帧启用malloc()临时缓冲需在main()中heap_init()注意malloc()在裸机需重定义sbrk()驱动已提供sysmem.c实现。若忘记初始化heapjpeg_parser.c中malloc()返回NULL状态机会卡死在JPEG_BODY。4. 常见问题排查那些让你怀疑人生却只需改1行寄存器的翻车现场现象、原因、解决必须一一对应拒绝模糊描述。以下5条均来自真实调试日志按发生频率排序4.1 现象摄像头初始化成功ov2640_init()返回OK但jpeg_get_frame()永远返回JPEG_NO_FRAME原因0x0E寄存器JPEG输出使能未正确写入0x80或写入后未等待足够时间OV2640需10ms稳定期。常见于ov2640_write_reg(0x0E, 0x80)后直接进入捕获循环未调用Delay_ms(10)。解决在ov2640_set_jpeg_mode()末尾强制添加Delay_ms(12)并在jpeg_capture_fsm()入口增加if(stateJPEG_IDLE) Delay_ms(1)防抖。4.2 现象首帧JPEG正常第二帧开始数据全为0x00或0xFF原因0x0D寄存器FIFO清空在每帧开始前未重置。OV2640内部FIFO满后不再输出新数据但PCLK仍翻转导致读取到无效电平。解决在jpeg_capture_fsm()每次进入JPEG_IDLE状态时插入ov2640_write_reg(0x0D, 0x00)。注意此操作需在PCLK停止期间执行加GPIO_ResetBits(GPIOA, GPIO_Pin_0)。4.3 现象图像出现规律性水平条纹每16行重复一次原因0x3a寄存器PCLK采样边沿设为0x00上升沿采样但硬件连接中PCLK信号存在15ns延迟导致采样点落在数据不稳定区。解决将0x3a改为0x04下降沿采样并同步修改jpeg_capture_fsm()中PCLK检测逻辑——由检测GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)1改为检测下降沿需记录上一状态。4.4 现象室内光照下图像严重偏蓝室外则发黄原因0x6AAWB使能设为0x01手动白平衡但未配置0x70~0x73R/G/B gain寄存器导致增益为默认值0x40色温失衡。解决若需自动白平衡确保0x6A0x00若需手动则必须成组配置0x700x52, 0x710x40, 0x720x4A, 0x730x40D65色温标准值缺一不可。4.5 现象串口打印JPEG_ERR_INVALID_LEN且frame_len恒为65535原因write_ptr变量溢出。驱动中write_ptr定义为uint16_t当帧长超64KB时自增回0导致frame_len write_ptr - 0计算错误。解决将write_ptr和frame_len类型统一改为uint32_t并在jpeg_switch_buffer()中重置为0UL。此Bug在ov2640_reg_list.xlsx第89行有注释“大帧长需32位索引”。5. 核心寄存器实战解析从ov2640_reg_list.xlsx里挖出的3个反直觉配置点ov2640_reg_list.xlsx不是简单参数表而是某开发者踩坑后整理的“血泪经验库”。以下3个寄存器配置点文档未强调但实测决定项目生死5.10x32JPEG量化表选择——不是“越小越好”而是要匹配硬件解码能力值效果适用场景风险0x00使用内置量化表Q1高压缩网络传输C8T6内存不足JPEG解码失败0x01使用内置量化表Q2中等本地存储画质损失可接受0x02使用内置量化表Q3低压缩裸机实时处理首选单帧≤130KBC8T6可缓存实测设0x320x02后640×480帧长稳定在122~128KBjpeg_parser.c中memcpy()拷贝耗时8ms留足时间给后续HOG特征提取。5.20x50JPEG质量值——0x28不是经验值而是内存带宽计算结果质量值0x50与帧长非线性相关。驱动作者在ov2640_reg_list.xlsx备注栏写下计算过程C8T6 GPIO读取带宽 12MHz / 8bit 1.5MB/s 目标帧率15fps → 单帧可用带宽 1.5MB/s ÷ 15 100KB 查OV2640 datasheet Table 12Q28对应122KB → 超出5%但PCLK时序余量允许 故Q28为极限值Q27128KB必超限因此0x500x28是硬算出来的边界值非随意选取。5.30x15PLL分频系数——改错一个bitPCLK直接变24MHz→36MHz0x15寄存器控制PLL倍频其bit0~bit2为分频因子N0x00→ N1 → PCLK12MHz原始晶振0x01→ N2 → PCLK24MHz默认0x02→ N3 → PCLK36MHz危险OV2640手册注明最大PCLK24MHz但实测0x150x02时JPEG流前半帧正常后半帧因时序超限出现0x00填充。解决方案在ov2640_init_phase1()中硬编码ov2640_write_reg(0x15, 0x01)禁止用户修改。6. 二次开发改造指南如何把OV2640驱动接入你的项目并让它真正“为你所用”别再满足于“能跑通例程”。当你需要把这套驱动嵌入自己的智能小车项目、或给毕业设计加个图像识别模块时以下改造路径经过3个真实项目验证每一步都附可立即执行的代码片段和避坑提示。6.1 步骤1解耦硬件抽象层HAL→LL→裸寄存器驱动默认使用STM32F103标准外设库SPL但你的项目可能用HAL或LL。改造核心是替换GPIO_ReadInputData()和Delay_us()// 若用HAL库重定义底层读取函数 uint8_t ov2640_gpio_read_data(void) { return (uint8_t)( HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) 0 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1) 1 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) 2 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3) 3 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4) 4 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) 5 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_6) 6 | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) 7 ); } // HAL_Delay_us 实现需在stm32f1xx_hal_conf.h中启用SYSTICK void Delay_us(uint16_t us) { uint32_t start HAL_GetTick(); while ((HAL_GetTick() - start) * 1000 us) { __NOP(); // 防止编译器优化掉空循环 } }注意HAL_GetTick()默认精度1ms此处需重写为基于SysTick-VAL的微秒计数否则Delay_us(5)变成Delay_ms(1)。驱动包中sys_tick.c已提供SysTick_DelayUs()函数直接调用即可。6.2 步骤2接入你的图像处理流水线JPEG→RGB565→算法jpeg_parser.c输出的是原始JPEG字节流你需要解码为RGB565供LCD显示或算法处理。推荐轻量级解码器minijpeg仅2KB代码改造jpeg_get_frame()使其返回解码后指针// 在jpeg_parser.h中添加 extern uint16_t *jpeg_decode_to_rgb565(const uint8_t *jpeg_data, uint32_t len); // 修改jpeg_get_frame() uint16_t *jpeg_get_frame_rgb565(void) { if (frame_ready) { static uint16_t rgb565_buf[640*480]; // 640×480×2 614KB → 改用malloc! uint16_t *rgb_ptr malloc(640*480*2); if (rgb_ptr) { jpeg_decode_to_rgb565(jpeg_buf_a, frame_len); memcpy(rgb_ptr, rgb565_buf, 640*480*2); } jpeg_switch_buffer(); return rgb_ptr; } return NULL; }血泪经验不要在中断中mallocjpeg_get_frame_rgb565()必须在主循环中调用且返回的rgb_ptr需由调用者free()。某同学在EXTI_IRQHandler中调用此函数导致heap碎片化运行2小时后malloc()返回NULL。6.3 步骤3添加自定义寄存器配置接口让非专业用户也能调参ov2640_reg_list.xlsx里有127个寄存器但用户只需改其中10个。驱动新增ov2640_user_config_t结构体typedef struct { uint8_t resolution; // 0320x240, 1640x480, 21280x960 uint8_t quality; // 0x00~0x3F uint8_t awb_en; // 0disable, 1enable uint8_t mirror; // 0normal, 1mirror uint8_t flip; // 0normal, 1flip } ov2640_user_config_t; void ov2640_apply_user_config(const ov2640_user_config_t *cfg) { switch(cfg-resolution) { case 0: ov2640_set_size_320x240(); break; case 1: ov2640_set_size_640x480(); break; case 2: ov2640_set_size_1280x960(); break; } ov2640_write_reg(0x50, cfg-quality); ov2640_write_reg(0x6A, cfg-awb_en); ov2640_write_reg(0x7F, cfg-mirror ? 0x01 : 0x00); ov2640_write_reg(0x7E, cfg-flip ? 0x01 : 0x00); }提示ov2640_set_size_1280x960()需额外配置0x4C~0x4FH/V输出窗口驱动已封装好直接调用即可。此接口让导师验收时“改个分辨率”只需3行代码而非翻查127行寄存器表。6.4 步骤4添加运行时诊断接口让调试不再靠猜在ov2640.c中暴露诊断函数通过串口实时查看关键状态void ov2640_print_diagnosis(void) { printf(OV2640 Diag:\r\n); printf( Frame Ready: %d\r\n, frame_ready); printf( Frame Len: %d KB\r\n, frame_len / 1024); printf( Err Count: %d\r\n, jpeg_err_count); printf( SCCB Retries: %d\r\n, sccb_retry_count); printf( PCLK Freq: %.2f MHz\r\n, get_pclk_frequency()); // 需实现 }配合printf重定向到USART1上电后每5秒自动打印异常时立刻定位是SCCB问题还是JPEG问题。从那以后我每次接到新硬件平台比如从F103换到F407都强制走一遍ov2640_reg_list.xlsx里的“阶段0复位→阶段1基础→阶段2尺寸→阶段3功能→阶段4启动”五步验证用示波器抓PCLK和D0波形确认每步后状态机是否推进。这多花的20分钟省下了后面三天抓耳挠腮的时间。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

DeepSeek API接入实战:用OpenAI Python SDK调用与成本控制

DeepSeek API接入实战:用OpenAI Python SDK调用与成本控制

看到这个标题,估计不少人会愣一下:OpenAI、DeepSeek、Python、API Key,怎么全搅在一起了?其实这组合在开发圈里一点也不奇怪。DeepSeek是当下热度极高的开源大语言模型,它的API接口在设计上一开始就兼容了OpenAI的调用…

📅 2026/10/17 11:04:34
AI短剧全栈生成平台深度拆解:从剧本到成片的自动化流程与工程实践

AI短剧全栈生成平台深度拆解:从剧本到成片的自动化流程与工程实践

AI短剧这个概念,前两年说出来还像是玩票,但今年实实在在地变了。我身边有做information流投放的团队,月产短剧从两部提到二十部,靠的不是扩招,而是把AI生成流水线嵌进了工作流——这就是Magic Drama这类全栈AI短剧生成…

📅 2026/10/17 11:04:34
无人机光伏板热成像缺陷检测数据集构建与VOC/YOLO格式转换

无人机光伏板热成像缺陷检测数据集构建与VOC/YOLO格式转换

无人机视角的光伏板热成像红外图像缺陷检测,听起来就是把相机挂到飞机上拍一圈,再丢给目标检测模型去跑。真正做过一遍才发现,这里面的坑比想象中多得多。从飞行高度到热像仪辐射定标,从缺陷类别定义到VOC和YOLO两种标注格式之间的…

📅 2026/10/17 11:04:34
MORE NEWS

更多资讯

📰

GitHub日榜热度建模:从star增量到技术趋势预测

1. 项目概述:这不是一个“项目”,而是一面实时映射技术生态的镜子“GitHub 热榜项目:日榜(2026-10-10)”这个标题,乍看像一份新闻简报,实则藏着一整套可复用的技术观测方法论。它不是某个具体开…

📰

STM32三线驱动74HC595级联:IO资源紧张下的数码管与LED扩展方案

简介:本资源是一套面向STM32初学者与嵌入式开发者的74HC595串行扩展驱动代码,专为解决GPIO资源受限场景下的数码管、LED矩阵等多路并行输出控制问题而设计,支持任意数量芯片级联,显著提升IO复用效率。压缩包仅含2个核心文件&#…

📰

PaddleOCR图片旋转90度识别失败?方向检测与校正实战

简介:本资源面向图像处理初学者与需要批量矫正图片方向的开发者,聚焦利用PaddleOCR底层能力解决图片旋转问题。包内共45个文件,以19个py脚本与17个pyc编译文件为主,另含3个onnx模型、2张jpg与1张png示例图、1个ttf字体及readme.md…

📰

Flutter跨端开发实战:在OpenHarmony上构建维修状态看板

1. 项目概述1.1 能做什么:维修车间里的“数字仪表盘”先说结论:这个项目,是给汽车维修门店/售后车间做的一个跨端“状态总览屏”。它解决的核心问题,是让前台接待、车间主管、维修技师都能在一块屏幕上随时掌握每辆在修车辆的实时…

📰

LexiLaw中文法律大模型:本地部署与推理优化实战

简介:LexiLaw 是一套面向法律从业者、法学院学生及对法律知识有需求的普通用户的中文法律大模型资源,基于 ChatGLM-6B 架构在法律领域数据集上微调而成,可用于法律咨询、条款解读、案例解析与法规查询等场景,帮助读者理解大模型在…

📰

更新DOM完全指南:从原生操作到虚拟DOM渲染机制

有人问更新DOM是什么操作,我认真想了想这个问题有人问“更新DOM是什么操作”的时候,往往是遇到了这样一种情况:代码里明明把数据改了,页面上却纹丝不动。或者更糟,页面动了,但输入框的焦点丢了、滚动条跳了…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬