循环处理YouTube API JSON数据时的子元素内容匹配问题
问题解决方案
核心问题拆解
- 重复追加时长:循环中未精准绑定当前视频对应的DOM元素,导致所有时长数据被插入到
#result下的所有子div中。 - 数据未定义:YouTube Data API请求是异步操作,循环变量的作用域未锁定,回调触发时变量已被后续迭代覆盖,无法匹配正确的视频项。
修复实现方案
1. 锁定迭代上下文+精准定位DOM
用$.each()遍历视频列表(替代普通for循环),给每个视频容器添加唯一标识属性,后续请求到时长后直接定位对应容器。
修复示例代码
$('#search-form').submit(function(e) { e.preventDefault(); const searchQuery = $('#search-input').val(); // 第一步:调用搜索API获取视频列表 $.get('https://www.googleapis.com/youtube/v3/search', { key: '你的API密钥', q: searchQuery, part: 'snippet', maxResults: 6, type: 'video' }, function(searchRes) { $('#result').empty(); // 遍历搜索结果,渲染基础信息并请求对应时长 $.each(searchRes.items, function(_, videoItem) { const videoId = videoItem.id.videoId; // 创建带唯一标识的视频容器 const $videoCard = $('<div class="video-card" data-vid="' + videoId + '"></div>'); $videoCard.append(`<h4>${videoItem.snippet.title}</h4>`); $('#result').append($videoCard); // 第二步:单独请求当前视频的时长数据 $.get('https://www.googleapis.com/youtube/v3/videos', { key: '你的API密钥', id: videoId, part: 'contentDetails' }, function(detailRes) { if (!detailRes.items.length) return; // 转换ISO 8601格式时长为可读格式 const rawDuration = detailRes.items[0].contentDetails.duration; const readableTime = parseYTDuration(rawDuration); // 精准定位当前视频容器,追加时长 $(`div[data-vid="${videoId}"]`).append(`<p>时长:${readableTime}</p>`); }); }); }); }); // 辅助函数:转换YouTube的ISO 8601时长为HH:MM:SS function parseYTDuration(duration) { const regex = /PT(\d+H)?(\d+M)?(\d+S)?/; const matches = duration.match(regex); const hours = matches[1] ? parseInt(matches[1]) : 0; const minutes = matches[2] ? parseInt(matches[2]) : 0; const seconds = matches[3] ? parseInt(matches[3]) : 0; return [ hours.toString().padStart(2, '0'), minutes.toString().padStart(2, '0'), seconds.toString().padStart(2, '0') ].join(':'); }
关键修复点
- 给每个视频容器添加
data-vid属性,作为唯一匹配标识,避免全局遍历子div导致的重复插入。 - 使用
$.each()遍历,确保每次迭代的上下文独立,解决异步回调时变量被覆盖的问题。 - 每个视频单独请求时长数据,直接绑定到自身容器,无需额外处理批量数据的索引匹配。
内容的提问来源于stack exchange,提问作者user19758032
相关产品推荐
相关产品推荐

