Vimeo 图片和 javascript
Vimeo images and javascript
所以我无法让我的缩略图系统正常工作。它从 vimeo 获取图像并将其放入 .所以我试着让它循环,因为这样看起来更好。
但我无法让它工作 :( 有人可以帮助我吗?
<div class="row">
<div class="col-sm-3"><img src="" id="img1" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img2" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img3" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img4" class="img-rounded" width="100%" height="200px"></img></div>
</div>
<br>
<div class="row">
<div class="col-sm-3"><img src="" id="img5" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img6" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img7" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img8" class="img-rounded" width="100%" height="200px"></img></div>
</div>
</div>
</body>
<script>
var ids = ["169971394", "169657641", "169569693", "169569661", "169569619", "169569539", "169569509", "169566439"]
var imgs= ["img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8"]
for (i = 0; i < 7; i++) {
$(document).ready(function () {
var vimeoVideoUrl = 'https://player.vimeo.com/video/' + ids[i];
console.log(vimeoVideoUrl);
var match = /vimeo.*\/(\d+)/i.exec(vimeoVideoUrl);
if (match) {
var vimeoVideoID = match[1];
$.getJSON('http://www.vimeo.com/api/v2/video/' + vimeoVideoID + '.json?callback=?', { format: "json" }, function (data) {
featuredImg = data[0].thumbnail_large;
console.log(imgs[i]);
$(imgs[i]).attr("src", featuredImg);
});
}
});
}
</script>
(以上是重要部分。)仅供参考:我为此使用 bootstrap 和 jquery。 (还有一些其他的,不过那些都不重要)
一些背景
在循环中做这种事情的复杂之处在于 $.getJSON()
是 异步的 ,而 for 循环是 同步的 .要基本了解差异,请查看 this answer。但这是总体思路:
Synchronous:事物按顺序执行。当一个操作完成时,下一个操作开始。
示例:
var a = 0; // This is executed first
a = a + 1; // This is executed second
异步:同步操作不等待异步操作完成才继续使用脚本
示例:
// This is executed first
var a = 0;
// This is executed 2nd, but the function inside won't be called for 1 second
setTimeout(function() {
// this is executed last, outputs 1
console.log(a);
}, 1000);
// this is executed third, before the function call
a = a + 1;
你的问题
在您的示例代码中,您正在同步操作中执行异步函数。通常,这没关系,您真的不必担心。当您尝试在异步函数中使用变量 i
,但变量 i
在同步操作 (for 循环)期间被更改 时,就会出现问题。
这是一个显示正在发生的事情的例子
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000)
}
考虑一下
现在,通过查看代码,您可能希望它等待 1 秒,然后将每个数字记录到控制台,例如
-> 0
-> 1
-> 2
-> 3
-> 4
渔获物
但是,如果您实际上 运行 上面的代码片段,您会看到它每次 5
都会记录 。这是因为当回调函数实际 运行.
时,变量 i
实际上的值为 5
但是如何呢?
怎么样? for 循环在每个 setTimout()
完成之前继续执行,等待 1 秒。所以当 1 秒结束时,循环已经递增 i
到中断循环的点,在这种情况下是 5
。
在您的问题中,回调函数中的一个简单的 console.log(i);
很可能会显示 7
八次,因为变量 i
仍在递增,而您的 $.getJSON()
实际上是在等待结果返回。当实际 返回结果时 ,循环可能完成 运行ning,并且 i
将等于 7
解决方案
为了确保我们在页面上以正确的顺序放置视频和图像,并且我们实际上将每张图像放置在正确的位置,我们需要针对这种异步行为做一些重要的变通办法。我对这段代码进行了评论,让您了解每行代码的作用。
// dom is ready to be manipulated
$(document).ready(function() {
// create an array of our video ids
var ids = [
"169971394",
"169657641",
"169569693",
"169569661",
"169569619",
"169569539",
"169569509",
"169566439"
];
// initialize an empty array that will eventually hold our videos
var videos = [];
// loop through our array of ids
ids.forEach(function(id, i) {
// because these are in order, ids[0] should be in #img1 etc
var image = '#img' + (i + 1);
// get your video url --not actually used in this code
var vimeoVideoUrl = 'https://player.vimeo.com/video/' + id;
// create an object that holds the information for this video that can
// be gathered *synchronously*
var v = {
id: id,
image: '#img' + (i + 1),
video: vimeoVideoUrl
};
// add this object to our initially empty array
videos.push(v);
/* after the loop ends, videos array might look like this
[
{
id: "169971394",
image: "#img1",
video: "https://player.vimeo.com/video/169971394"
},
{
... next video
} ... for each video
]
*/
// do our ajax operation to get the rest of the video information
$.getJSON(
'https://www.vimeo.com/api/v2/video/' + id + '.json?callback=?', {
format: "json"
},
// REMEMBER -- this function is *asynchronous* and we can't trust the
// value of the increment from our loop, so this is relatively complex
function(data) {
// get the id of the returned video
var id = data[0].id;
// get the thumbnail
var thumb = data[0].thumbnail_large;
// loop through our videos array
videos.forEach(function(v, i) {
// find the element of the array with the id that was just returned
if (v.id == id) {
// and add the thumbnail url to the object
videos[i].thumbnail = thumb;
/* an element of the videos array will look like this when the callback
has finished for that video
{
id: "169971394",
image: "#img1",
video: "https://player.vimeo.com/video/169971394",
thumbnail: "https://i.vimeocdn.com/video/574879586_640.jpg"
}
notice that the thumbnail property is now set
*/
}
});
// each time we execute the callback, we need to know if it's the last
// execution, so we will need to check if every callback has been completed
// this condition returns false if the thumbnail element is not assigned
// to every object in the videos array, which would tell us that this isn't
// the last execution of the callback
if (videos.every(function(v) {
return v.thumbnail !== undefined
})) {
// if this is the last execution of the callback,
// loop through each item in the videos array
videos.forEach(function(video) {
// set the src of the video's corresponding image to the url of the thumbnail
$(video.image).attr("src", video.thumbnail);
});
}
}
);
});
});
https://jsfiddle.net/o82L6q48/2/ 实际操作
请注意,这可能比实际需要的更复杂,但它确实有效,我希望你能从中学到一些东西。
所以我无法让我的缩略图系统正常工作。它从 vimeo 获取图像并将其放入 .所以我试着让它循环,因为这样看起来更好。
但我无法让它工作 :( 有人可以帮助我吗?
<div class="row">
<div class="col-sm-3"><img src="" id="img1" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img2" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img3" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img4" class="img-rounded" width="100%" height="200px"></img></div>
</div>
<br>
<div class="row">
<div class="col-sm-3"><img src="" id="img5" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img6" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img7" class="img-rounded" width="100%" height="200px"></img></div>
<div class="col-sm-3"><img src="" id="img8" class="img-rounded" width="100%" height="200px"></img></div>
</div>
</div>
</body>
<script>
var ids = ["169971394", "169657641", "169569693", "169569661", "169569619", "169569539", "169569509", "169566439"]
var imgs= ["img1", "img2", "img3", "img4", "img5", "img6", "img7", "img8"]
for (i = 0; i < 7; i++) {
$(document).ready(function () {
var vimeoVideoUrl = 'https://player.vimeo.com/video/' + ids[i];
console.log(vimeoVideoUrl);
var match = /vimeo.*\/(\d+)/i.exec(vimeoVideoUrl);
if (match) {
var vimeoVideoID = match[1];
$.getJSON('http://www.vimeo.com/api/v2/video/' + vimeoVideoID + '.json?callback=?', { format: "json" }, function (data) {
featuredImg = data[0].thumbnail_large;
console.log(imgs[i]);
$(imgs[i]).attr("src", featuredImg);
});
}
});
}
</script>
(以上是重要部分。)仅供参考:我为此使用 bootstrap 和 jquery。 (还有一些其他的,不过那些都不重要)
一些背景
在循环中做这种事情的复杂之处在于 $.getJSON()
是 异步的 ,而 for 循环是 同步的 .要基本了解差异,请查看 this answer。但这是总体思路:
Synchronous:事物按顺序执行。当一个操作完成时,下一个操作开始。
示例:
var a = 0; // This is executed first
a = a + 1; // This is executed second
异步:同步操作不等待异步操作完成才继续使用脚本
示例:
// This is executed first
var a = 0;
// This is executed 2nd, but the function inside won't be called for 1 second
setTimeout(function() {
// this is executed last, outputs 1
console.log(a);
}, 1000);
// this is executed third, before the function call
a = a + 1;
你的问题
在您的示例代码中,您正在同步操作中执行异步函数。通常,这没关系,您真的不必担心。当您尝试在异步函数中使用变量 i
,但变量 i
在同步操作 (for 循环)期间被更改 时,就会出现问题。
这是一个显示正在发生的事情的例子
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000)
}
考虑一下
现在,通过查看代码,您可能希望它等待 1 秒,然后将每个数字记录到控制台,例如
-> 0
-> 1
-> 2
-> 3
-> 4
渔获物
但是,如果您实际上 运行 上面的代码片段,您会看到它每次 5
都会记录 。这是因为当回调函数实际 运行.
i
实际上的值为 5
但是如何呢?
怎么样? for 循环在每个 setTimout()
完成之前继续执行,等待 1 秒。所以当 1 秒结束时,循环已经递增 i
到中断循环的点,在这种情况下是 5
。
在您的问题中,回调函数中的一个简单的 console.log(i);
很可能会显示 7
八次,因为变量 i
仍在递增,而您的 $.getJSON()
实际上是在等待结果返回。当实际 返回结果时 ,循环可能完成 运行ning,并且 i
将等于 7
解决方案
为了确保我们在页面上以正确的顺序放置视频和图像,并且我们实际上将每张图像放置在正确的位置,我们需要针对这种异步行为做一些重要的变通办法。我对这段代码进行了评论,让您了解每行代码的作用。
// dom is ready to be manipulated
$(document).ready(function() {
// create an array of our video ids
var ids = [
"169971394",
"169657641",
"169569693",
"169569661",
"169569619",
"169569539",
"169569509",
"169566439"
];
// initialize an empty array that will eventually hold our videos
var videos = [];
// loop through our array of ids
ids.forEach(function(id, i) {
// because these are in order, ids[0] should be in #img1 etc
var image = '#img' + (i + 1);
// get your video url --not actually used in this code
var vimeoVideoUrl = 'https://player.vimeo.com/video/' + id;
// create an object that holds the information for this video that can
// be gathered *synchronously*
var v = {
id: id,
image: '#img' + (i + 1),
video: vimeoVideoUrl
};
// add this object to our initially empty array
videos.push(v);
/* after the loop ends, videos array might look like this
[
{
id: "169971394",
image: "#img1",
video: "https://player.vimeo.com/video/169971394"
},
{
... next video
} ... for each video
]
*/
// do our ajax operation to get the rest of the video information
$.getJSON(
'https://www.vimeo.com/api/v2/video/' + id + '.json?callback=?', {
format: "json"
},
// REMEMBER -- this function is *asynchronous* and we can't trust the
// value of the increment from our loop, so this is relatively complex
function(data) {
// get the id of the returned video
var id = data[0].id;
// get the thumbnail
var thumb = data[0].thumbnail_large;
// loop through our videos array
videos.forEach(function(v, i) {
// find the element of the array with the id that was just returned
if (v.id == id) {
// and add the thumbnail url to the object
videos[i].thumbnail = thumb;
/* an element of the videos array will look like this when the callback
has finished for that video
{
id: "169971394",
image: "#img1",
video: "https://player.vimeo.com/video/169971394",
thumbnail: "https://i.vimeocdn.com/video/574879586_640.jpg"
}
notice that the thumbnail property is now set
*/
}
});
// each time we execute the callback, we need to know if it's the last
// execution, so we will need to check if every callback has been completed
// this condition returns false if the thumbnail element is not assigned
// to every object in the videos array, which would tell us that this isn't
// the last execution of the callback
if (videos.every(function(v) {
return v.thumbnail !== undefined
})) {
// if this is the last execution of the callback,
// loop through each item in the videos array
videos.forEach(function(video) {
// set the src of the video's corresponding image to the url of the thumbnail
$(video.image).attr("src", video.thumbnail);
});
}
}
);
});
});
https://jsfiddle.net/o82L6q48/2/ 实际操作
请注意,这可能比实际需要的更复杂,但它确实有效,我希望你能从中学到一些东西。