Random Imgur Images Using Vanilla JavaScript

Ciprian on Thursday, October 1, 2020 in AJAX and Fetching Data, JavaScript DOM

NEW! Learn JavaScript by example. Code snippets, how-to's and tutorials. Try now!

I found this old code I used for an old forum a long time ago and I decided to bring it up-to-date and see if it still works. Turns out is does!

I have improved the code a bit, added Flex CSS and lazy loading.

So, if you’re ever in need of getting 50 random Imgur images, use the code below. A live demo is available here.

⚠️ Note that, as Imgur is a free image sharing service, some images may not be suitable for work or for children.

HTML

<h1>Random Imgur Images</h1>

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

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

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

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) : "";
    }
};

document.getElementById('random').addEventListener('click', function(e) {
    Imgur.fetch(50);
});

CSS

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

Related posts

Leave a Reply

Your email address will not be published. Required fields are marked *