我循环播放了一组div,这些div为YouTube视频获取并显示其标题,说明等。我循环播放的div看起来像这样:
<div class="tutorialVideoDataContainer" data-clipid="xxxxxxxxxxx"></div>
<div class="tutorialVideoDataContainer" data-clipid="xxxxxxxxxxx"></div>
<div class="tutorialVideoDataContainer" data-clipid="xxxxxxxxxxx"></div>
<div class="tutorialVideoDataContainer" data-clipid="xxxxxxxxxxx"></div>
<div class="tutorialVideoDataContainer" data-clipid="xxxxxxxxxxx"></div>
由于某种原因,循环将所有信息添加到这些div中的最后一个,而不是将信息应用于循环内的当前div。知道为什么会这样吗?
而且,作为一个子问题,为什么我不能在ajax呼叫中到达我?我必须设置tutorial = tutorials [i]并将孩子们附加到教程而不是教程[i],但我不能在ajax部分中使用教程[i]。我无法理解其中的区别。
(function () {
var tutorials = document.getElementsByClassName('tutorialVideoDataContainer');
for (var i = 0; i < tutorials.length; i++) {
var tutorial = tutorials[i];
console.log(i);
console.log(tutorial);
console.log(tutorials[i]);
var id = tutorial.getAttribute('data-clipid');
$.ajax({
url: "http://gdata.youtube.com/feeds/api/videos/" + id + "?v=2&alt=json",
dataType: "jsonp",
success: function (data) {
var title = data.entry.title.$t;
var description = data.entry.media$group.media$description.$t;
var duration = data.entry.media$group.media$content[0].duration;
var thumbnail = data.entry.media$group.media$thumbnail[3].url;
if (title.length > 0) {
var titleElement = document.createElement("h3");
titleElement.innerText = title;
tutorial.appendChild(titleElement);
}
if (description.length > 0) {
var descriptionElement = document.createElement("p");
descriptionElement.innerText = description;
tutorial.appendChild(descriptionElement);
}
var minutes = Math.floor(duration / 60);
var seconds = duration - minutes * 60;
var durationElement = document.createElement("p");
durationElement.innerText = minutes + ":" + seconds;
tutorial.appendChild(durationElement);
var clickLink = document.createElement("a");
clickLink.className = "showOverlayVideo";
var thumbnailElement = document.createElement("img");
thumbnailElement.src = thumbnail;
thumbnailElement.alt = title;
clickLink.appendChild(thumbnailElement);
tutorial.appendChild(clickLink);
}
});
}
})();
答案 0 :(得分:2)
如果你遍历数组和crate闭包你访问数组的索引,你访问变量的引用而不是它的副本,所以当所有异步代码完成时你最终会引用最后一个元素。要修复它,您需要使用新引用创建另一个闭包:
for (var i = 0; i < tutorials.length; i++) {
(function(tutorial) {
// you can use tutorial inside
})(tutorials[i]);
}
答案 1 :(得分:0)
由于javascript事件循环的工作方式,循环在ajax请求返回之前完成运行。因此,当他们这样做时,变量教程被设置为循环中的最后一个。
从youtube api返回的数据是否包含剪辑ID,然后您可以使用它来在回调中而不是在循环内查找正确的dom元素。
答案 2 :(得分:0)
我的猜测是,因为$.ajax()
不是阻塞函数,所以循环在ajax完成之前就完成了。这将导致执行路径看起来像这样:
希望有帮助/有意义。