Random Imgur images

Load random Imgur images

by Ciprian Popescu

HTML

<h1>Random Imgur Images</h1>
<p>
    <a href="https://getbutterfly.com/random-imgur-images-using-vanilla-javascript/">Random Imgur Images Using Vanilla JavaScript</a>
</p>

<p id="info"></p>

<ul id="images">
</ul>

<p>
    <button id="random">Show me more!</button>
</p>

CSS

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    font-size: 14px;
    line-height: 1.5;
    color: #24292e;
    background-color: #ffffff;
    padding: 24px;
}
button {
    font-family: inherit;
    font-size: inherit;
}

#info {
    font-size: small;
}

#images {
    margin: 24px 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
}
#images li {
    list-style: none;
    margin: 2px;
    padding: 0;
    width: 48px;
    height: 48px;
}
#images li img {
    border-radius: 3px;
}

JavaScript

let Imgur = {
    fetch: function(num) {
        let self = this;

        self.total = num;
        self.done = 0;
        self.failures = 0;
        self.start = +new Date;

        document.getElementById('images').innerHTML = '';

        for (let x = 0; x < num; x++) {
            self.hunt(function(id) {
                self.done++;

                const li = document.createElement('li');

                li.innerHTML = `<li><a href="https://imgur.com/${id}"><img src="https://i.imgur.com/${id}s.png" height="48" width="48" loading="eager"></a></li>`;

                document.getElementById('images').appendChild(li);

                self.update();
            });
        }
    },
    update: function() {
        let interval = new Date - this.start;

        function speed(v) {
            return (~~(v / interval * 1e5)) / 100;
        }
        document.getElementById('info').innerHTML = (this.done < this.total ? "Loading.. " + this.done + "/" + this.total + " (" + this.failures + " failures" + ") " : "Done. ") + "[" + speed(this.failures + this.done) + " req/s - " + speed(this.done) + " img/s]";
    },

    hunt: function(cb) {
        let self = this,
            id = self.random(5),
            img = new Image;
        self.update();
        img.src = "https://imgur.com/" + id + "s.png";
        img.onload = function() {
            if (img.width == 161 && img.height == 81) {
                // assume this is an imgur error image, and retry.
                fail();
            } else {
                cb(id);
            }
        }
        img.onerror = fail; // no escape.
        function fail() {
            self.failures++;
            self.update();
            self.hunt(cb);
        }
    },

    random: function(len) {
        let chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
        return len ? chars.charAt(~~(Math.random() * chars.length)) + this.random(len - 1) : "";
   ...