【问题标题】:Execute function after loading image array加载图像数组后执行函数
【发布时间】:2020-05-12 07:11:30
【问题描述】:

我在页眉图片加载后执行脚本:

objImg = new Image(); 
objImg.src = '/images/header.jpg';
objImg.onload = function() {
   $('#myDiv').fadeIn(500);
}

这很好用。但是,在其中一个页面上,我需要在加载四个图像而不是一个图像后执行它。有没有办法修改它使其成为一个数组而不是一个图像?

【问题讨论】:

    标签: jquery arrays image function onload


    【解决方案1】:

    我会使用这样的东西。

    在您的问题中使用相同的方法..

    对于图像数组,给img标签一个类说img

    现在找出您的页面中有多少张图片需要等待。

    var waitImageCount = $('.image-wait-for-load').length;

    检查所有图像是否已加载的代码。

    $(document /* or what ever */).on('load', '.image-wait-for-load', function() {
      waitImageCount--; // decrease the counter
    
      if(waitImageCount === 0) {
        // all images are loaded.
        // Do what ever you like
      }
    }); 
    

    请注意这个未经测试的代码,但我希望这样的东西应该可以工作。

    【讨论】:

    • 刚刚投了赞成票!因为即使它不处理错误,这种方法对我来说也是有创意和新的:)
    【解决方案2】:

    可以使用here 之类的 Promise 来完成。或者在将它们的源存储在并行数组中时简单地循环,并在预加载所有图像时使用回调函数。 并行数组在加载错误期间也很有用,因此我们可以使用它来仅显示预加载的有效图像。

    更复杂的方法是在使用 XMLHttpRequest() 预加载图像之前添加一个函数来测试图像的可用性;或 ajax。

    请注意,我在这里使用假图片来测试加载失败。

    var pix = new Array('https://image.shutterstock.com/image-photo/colorful-hot-air-balloons-flying-260nw-1033306540.jpg','https://images.fineartamerica.com/images-medium-large-5/hot-air-balloons-over-hay-bales-sunset-landscape-matthew-gibson.jpg','https://iso.500px.com/wp-content/uploads/2014/07/big-one.jpg','https://some.thing/undefined.jpg','https://cdn-media.rtl.fr/cache/4gx11M-ZCLtBdzqGMR2TWA/880v587-0/online/image/2019/1212/7799676803_l-enfant-de-the-mandalorian-est-la-star-de-la-galaxie.jpg');
     var total = pix.length;
     var ctr = 0;
     var cache=[];
     
    
    for(var i=0; i<total; i++){
        var img = new Image();
        img.src = pix[i];    
        //We push it to the cached elements list
        cache.push(img);
        img.onload = function(){
            
            console.log('Pic loaded!');
            ctr++;
            //When all are loaded
            if(ctr == total){
                console.log('All done ;) ');
                //We append them to the targeted div 
                WellDone();
            }
        }
        img.onerror = function(){
            //Because we didn't test the picture loading before adding it, we have to remove the failing image from the array
            cache.splice(i, 1);
            ctr++;
            if(ctr == total){
                console.log('All done ;) ');
                //We append them to the targeted div 
                WellDone();
            }        
        }
    
    }
    
    function WellDone(){
        //finally here things could run in a sequence!
        for (var i = 0; i < cache.length; i++) {
        $('#myDiv').append(cache[i]);
        }
        
        cache=[];
    $('#myDiv').fadeIn(500);
    }
    #myDiv{
    display:none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="myDiv"></div>

    【讨论】:

      【解决方案3】:

      下面的演示使用async function and await keyword,以便在客户端(您)和给定endpoint (first parameter) 的实时测试服务器之间使用Promise controls the asynchronous interaction。传递 DOM 元素的 selector(第二个可选参数)以指定渲染图像的位置(如果未定义,则默认为 "body")。

      fetchImages("https://sub.domain.tld/path/to/json", "tagName#id.className[attribute]"/*or "body"*/)
      

      fetch() 是一个异步函数,它通过await 关键字保证对请求数据的响应或拒绝。 .json() 方法(前面也有 await)检索 JSON。

      const response = await fetch(`https://api.myjson.com/bins/19fk22`);
      let imgArray = await response.json();
      /* At this point the JSON is stored in a variable called imgArray
      imgArray = [
        "https://i.ibb.co/hZj77BZ/lena01.jpg",
        "https://i.ibb.co/7XxsBr5/lena02.png",
        "https://i.ibb.co/X7SCb3w/lena03.png"
      ]
      */
      

      接下来,JSON 数组(又名imgArray)通过数组方法.forEach((src, idx) =&gt; {... 运行。 imgArray 中的每个 url(src 第一个参数)都会被处理。以下是正在处理的第一个图像 url 的分步细分(注意第二个参数 idx 在步骤 #3 中是如何使用的):

      1. 引用将放置图像的 DOM 元素

        const node = document.querySelector('.gallery')
        // <header class="gallery">|<= images will be inserted here =>|</header>
        
      2. 提取图片文件名.split()

         let name = src.split('/')
         // ['https:', 'i.ibb.co', 'hZj77BZ', 'lena01.jpg']
         .pop()
         // 'lena01.jpg'
         .split('.')
         // ['lena01', 'jpg']
         .shift();
         // 'lena01'
        
      3. htmlStringtemplate literal 分配给变量(let html),然后插入${values} 和/或${expressions}

         let html = `
        <figure style="animation: ${3 * (idx+1)}s fadeIn">`
        /* <figure style="animation: 3s fadeIn">
        Each iteration is assigned an increased CSS animation-duration value.
        The first image fades in for 3sec, the second image fades in for 6sec, third 9sec, etc.
        The actual code for the animation is in the CSS.
        */
          `<img src="${src}">`
          // <img src="https://i.ibb.co/hZj77BZ/lena01.jpg">
          `<figcaption>${name}</figcaption>`
          /* <figcaption>LENA01</figcaption>
          The name value from step #2 is inserted as a caption and styled by CSS
          */ 
        `</figure>`;
        node.insertAdjacentHTML("beforeend", html);
        /* .insertAdjacentHTML(position, htmlString) is .innerHTML on steroids
        @Param: [Position]: "beforebegin", "afterbegin", "beforeend", or "afterend"
        @Param: [htmlString]: strongly suggest that template literals be used instead of literal strings
        

      演示

      const endpoint = `https://api.myjson.com/bins/19fk22`;
      
      const fetchImages = async(endpoint, selector = "body") => {
        const response = await fetch(endpoint);
        let imgArray = await response.json();
        imgArray.forEach((src, idx) => {
          const node = document.querySelector(selector);
          let name = src.split('/').pop().split('.').shift();
          let html = `
          <figure style="animation: ${3 * (idx+1)}s fadeIn">
            <img src="${src}">
            <figcaption>${name}</figcaption>
          </figure>`;
          node.insertAdjacentHTML("beforeend", html);
        });
      }
      
      fetchImages(endpoint, '.gallery');
      .gallery {
        display: flex;
        justify-content: center;
        width: 96%;
        margin: 10px auto;
        padding: 5px;
        background: rgb(138, 56, 201);
      }
      
      figure {
        width: 50vw;
        margin: 10px 2.5px 5px;
      }
      
      figcaption {
        font: 700 small-caps 3vw/1 Arial;
        color: gold;
        text-align: center;
      }
      
      img {
        width: 100%;
        height: auto;
      }
      
      @keyframes fadeIn {
        from {
          opacity: 0;
        }
        50% {
          opacity: 0.66;
        }
        to {
          opacity: 1;
        }
      }
      &lt;header class='gallery'&gt;&lt;/header&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多