img标签onerror事件解决无限循环报错

当<img>标签中的图片加载失败时,页面上会出现不雅观的碎片图标。解决这个问题的方法包括替换默认图片和利用onerror事件。通过在onerror事件中设置图片源为备用图片,例如'static/images/nop.svg',可以确保即使原图无法加载,也能显示美观的占位符。这种方法能有效提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

问题:img标签中的src图片加载失败,原来的图片位置会出现一个碎片图标,这样让人很不爽,如何变得美观些呢

在这里插入图片描述


原因分析:

由于反显资源找不到或者路径不存在,就会按着img默认处理方式进行处理

解决方案:

1. 找一张默认图片进行替换

2. 利用onerror事件进行触发

3. onerror事件存在重复触发的现象

<img src="url" onerror= "this.οnerrοr='';this.src='static/images/nop.svg'">

即可解决
在这里插入图片描述

### 解决 SD_MMC 读取时因缓存字节数配置引发的报错问题 以下是针对 `sd_mmc` 文件系统在调用 `lv_fs_read` 方法时发生错误的具体原因分析及解决方案。 --- #### 一、SD_MMC 报错的根本原因 1. **缓存大小不足** 当尝试从 SD 卡读取大文件(如高分辨率图像)时,如果缓存区不足以容纳单次读取的数据量,则可能会触发错误。这通常表现为返回值小于预期或直接抛出异常[^1]。 2. **未正确初始化缓冲区** 缓冲区未被适当分配或清零也可能导致不可预测的行为。例如,在某些平台上,未初始化的内存区域可能包含随机数据,从而干扰正常的 I/O 流程[^2]。 3. **文件系统驱动冲突** 不同版本的 ESP-IDF 或第三方库之间可能存在兼容性问题。特别是当多个组件试图同时控制同一物理设备时,容易引起资源争抢现象[^3]。 4. **硬件限制** 部分开发板对连续 DMA 数据长度存在上限约束。一旦超出该范围即会产生中断信号而非完成请求操作[^4]。 --- #### 二、具体解决措施 ##### (一)调整缓存大小 重新规划适合当前应用需求的最佳缓冲方案至关重要。下面给出几种常见做法供参考: 1. **固定大小全局变量** 创建一个足够大的静态数组作为共享存储空间用于所有涉及外部介质的操作过程之中。 ```c static uint8_t global_cache[8192]; ``` 2. **动态申请堆内存** 根据实际运行环境灵活决定所需容量并通过标准 C 函数 malloc/free 进行管理。 ```c size_t desired_size = 16 * 1024; // Example value void* dynamic_buffer = heap_caps_malloc(desired_size , MALLOC_CAP_DMA); if(!dynamic_buffer){ printf("Memory allocation failed!"); } ... free(dynamic_buffer); ``` 注意:无论采用哪种方式都务必保证其生命周期覆盖整个交互周期以防中途释放造成悬空指针隐患。 ##### (二)增强健壮性的额外步骤 除了单纯改变 buffer dimension 外还应该考虑加入更多的防护机制来应对潜在风险情况: 1. **边界条件校验** 在每次执行前先确认输入参数合法性再继续后续动作可有效降低意外状况发生的概率. ```c if(btr > MAX_ALLOWED_TRANSFER || !buf ){ return LV_FS_RES_ERR; } ``` 2. **超时保护设定** 对长时间未能响应的任务实施强制终止以免陷入死循环浪费计算资源. ```c TickType_t timeout_ticks = pdMS_TO_TICKS(500); // Half second limit BaseType_t result = xQueueReceive(queue_handle, &data_received, timeout_ticks ); if(result != pdTRUE){ handle_timeout(); } ``` 3. **日志跟踪记录** 利用串口打印或者专用调试接口捕获实时状态变化有助于快速定位故障源头所在位置. ```c log_i("Attempting to fetch %d bytes starting at offset %lld.",btr,*br); ``` --- #### 三、综合案例演示 这里提供一段整合以上要点后的改进版代码片段帮助理解整体思路流程: ```c // Predefine constants and structures here... #define DEFAULT_CACHE_LEN (1<<13) /* 8KB */ typedef struct{ semphr_t lock; uint8_t data[]; }custom_buffer_s; static custom_buffer_s* create_custom_buf(size_t len){ custom_buffer_s* cbp=(custom_buffer_s*)heap_caps_aligned_alloc( 32,sizeof(custom_buffer_s)+len,MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); if(cbp!=NULL){ memset(cbp->data,0,len); cbp->lock=xSemaphoreCreateMutex(); } return cbp; } void destroy_custom_buf(custom_buffer_s* buf_ptr){ if(buf_ptr && buf_ptr->lock){ vSemaphoreDelete(buf_ptr->lock); } heap_caps_free(buf_ptr); } lv_fs_res_t fs_read(lv_fs_drv_t * drv,void * dest,uint32_t count,uint32_t * actual_count_p){ lv_fs_res_t outcome=LV_FS_RES_FAIL; custom_buffer_s* local_store=drv->user_data; if(xSemaphoreTake(local_store->lock,portMAX_DELAY)==pdPASS){ FILE* fp=fopen(drv->letter,"rb+"); if(fp){ fseek(fp,dst_offset_from_context(),SEEK_SET); const ssize_t read_amt=fread(dest,count,1,fp); fclose(fp); if(read_amt>0){ *actual_count_p=read_amt; outcome=LV_FS_RES_OK; } } xSemaphoreGive(local_store->lock); } return outcome; } int main(){ init_lvgl_env(); // Assume this sets up screen etc.. custom_buffer_s* img_loader=create_custom_buf(DEFAULT_CACHE_LEN); if(img_loader){ lv_fs_drv_t sdcard_driver={0}; sdcard_driver.letter='/'; sdcard_driver.user_data=img_loader; sdcard_driver.read_cb=&fs_read; register_and_mount(&sdcard_driver); draw_ui_elements_with_images(); cleanup_on_exit(img_loader,&sdcard_driver); }else{ report_error("Buffer creation failure."); } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别动我代码儿

感谢技术精进的你,加油不负韶华

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值