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/ 实际操作

请注意,这可能比实际需要的更复杂,但它确实有效,我希望你能从中学到一些东西。