简体   繁体   English

从Java脚本将图像加载为base64调用

[英]Loading images as base64 calls from Javascript

I am trying to implement a small photo show via a django webserver. 我正在尝试通过django网络服务器实现一个小型照片展示。 Below you can find the javascript code that loads the pictures into the images array and changes the images every x miliseconds. 在下面,您可以找到将图片加载到images数组并每x毫秒更改一次图片的javascript代码。 It works if I only load one picture (without the loop) from my django server but it stops working with any kind of loop. 如果我仅从django服务器加载一张图片(无循环),它将起作用,但是它停止使用任何类型的循环。

I would love to know why it does not work this way and would be more than happy to receive some other feedback about code improvements. 我很想知道为什么它不能以这种方式工作,并且非常乐意收到其他有关代码改进的反馈。 I am not very familiar with ajax calls yet. 我对ajax调用还不太熟悉。

Moreover: Django Templates Engine provides a easy way to simplify urls used in the templates. 此外:Django模板引擎提供了一种简化模板中使用的URL的简便方法。 Is there a way to use the {{% url %}} tag inside a .js File as well? 是否可以在.js文件中使用{{% url %}}标签?

window.images = [];
window.current = 0;
window.imageCount = 2;


function loadImages(){
    for(var i = 0; i < window.imageCount; i++){
        loadNextImage(i);
    }
    showImage();
}

function loadNextImage(i) {
    // https://wiki.selfhtml.org/wiki/JavaScript/XMLHttpRequest/
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            window.images.push("data:image/jpeg;base64," + xmlhttp.responseText);
        }
    };
    xmlhttp.open('GET', "http://127.0.0.1:8000/mirror/"+i);
    xmlhttp.send(null);
}

function showImage() {
    if(window.current >= window.imageCount){
        window.current = 0;
    }
    alert("current window count = "+ window.current);
    document.getElementById('imgshow').src = window.images[window.current];
    window.current = window.current + 1;
    setTimeout(showImage, 50000);
}

The direct problem you are encountering is because XMLHttpRequest is Asynchronous and you are dealing with a race condition. 您遇到的直接问题是因为XMLHttpRequest异步的,并且您正在处理竞争条件。 Here is what your code now is doing: 这是您的代码现在正在执行的操作:

  1. Start a loop and tell the browser to que 2 XMLHttpRequests . 开始循环,并告诉浏览器查询2个XMLHttpRequests
  2. Perform the showImage method (even though we have no idea if those 2 AJAX Requests above have returned yet.) 执行showImage方法(即使我们不知道上面的那两个AJAX请求是否已经返回)。
  3. An exception is thrown at this line: document.getElementById('imgshow').src = window.images[window.current]; 在此行引发异常: document.getElementById('imgshow').src = window.images[window.current]; because window.images is empty. 因为window.images为空。
  4. setTimeout(showImage, 50000); is never executed because of the exception at step 3. 由于步骤3中的异常,永远不会执行。

Moving the setTimeout above the document.getElementById('imgshow').src = window.images[window.current]; setTimeout移动到document.getElementById('imgshow').src = window.images[window.current];上方 line might work. 线可能有效。 However, this is a bad idea. 但是,这是一个坏主意。

One solution would be to remove the loop at all, and lazy load the images (only load them once they are needed) as seen below: 一种解决方案是完全删除循环,然后延迟加载图像(仅在需要它们时才加载它们),如下所示:

 window.images = []; window.current = 0; window.imageCount = 2; function loadNextImage(i, callback) { // https://wiki.selfhtml.org/wiki/JavaScript/XMLHttpRequest/ var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { window.images.push("data:image/jpeg;base64," + xmlhttp.responseText); callback.call(); } }; xmlhttp.open('GET', "http://127.0.0.1:8000/mirror/"+i); xmlhttp.send(null); } // Increments the image counter and loads the image if needed. function stepImage() { // If we have reached the end of the images, restart. if(window.current >= window.imageCount){ window.current = 0; } // Make sure that the image is loaded in the images array, // if not, load the image, then show it. if(window.images.length <= window.current) { loadNextImage(window.current, showImage); } // If it's already loaded, just show it. else showImage(); } // Displays an image onto the page. function showImage() { document.getElementById('imgshow').src = window.images[window.current]; // The counter is not incremented until the image is shown! window.current++; } // Set a timer to render future images. setInterval(stepImage, 3000); // Render the first image. stepImage(); 
 <img id="imgshow" /> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM