Change order of images on page load

If I have 5 images (doesn’t matter the exact number - could be 3 or 7 etc.) the exact same size going down the page, is it possible with JS to change the order? So for example: image 1 2 3 4 5 is the first load and then if you refresh the page, the order would be 3 4 2 5 1 down the page, etc.

Yes it is. You can pick any element and insert it before all of the others or append it to the end of the list.

1 Like

Would it be correct to say that would be different than a randomizer? So would this be dealing with an array and then reordering its position on the page every time its refreshed?

You can do it like a randomizer, by moving each item to either the start or end of a new node (called a document fragment), and when done, replacing the old one with the new one.

1 Like
<script>
function myFunction() {
    document.getElementById("image4").style.order = "4";
    document.getElementById("image3").style.order = "3";
    document.getElementById("image1").style.order = "1";
    document.getElementById("image2").style.order = "2";
}
</script>

And then you have a DIV with an ID in the body?

Something like this?

No, nothing like that. That cannot change the order of the elements on the page.

First you get a list of the children elements that you want to sort:

var numbers = document.querySelector('#numbers');
var list = Array.from(numbers.children);

Then you can randomize that list. There are a variety of different ways, but one way is to sort it returning random values or -1, 0, or 1.

list.sort(function(a, b) {
  return -1 + Math.random() * 3; // -1, 0, or 1
});

A more complex way to randomise it is to use a fisher-yates (knuth) shuffle instead, for which different algorithms are found at https://rosettacode.org/wiki/Knuth_shuffle#JavaScript

Then you can remove the old set of elements, and replace them with the new set.

while (numbers.children.length > 0) {
  numbers.removeChild(numbers.children[0]);
}
list.forEach(function(el) {
  numbers.appendChild(el);
});

All in all you end up with the following code:

var numbers = document.querySelector('#numbers');
var list = Array.from(numbers.children);
var newlist;

list.sort(function(a, b) {
  return -1 + Math.random() * 3; // -1, 0, or 1
});

while (numbers.children.length > 0) {
  numbers.removeChild(numbers.children[0]);
}
list.forEach(function(el) {
  numbers.appendChild(el);
});

You can see this all in action at the following test page: https://jsfiddle.net/0azkL7s9/1/

1 Like

When I go to your test page I see the order. When I refresh, the same order writes to the page. In your example, are the numbers down the page suppose to change orders?

It works in Chrome. I am using IE and that must be the reason it didn’t change.

There can be trouble using Array.from on older browsers, such as IE, so we’ll use a simple for loop for that:

for (var i = 0; i < numbers.children.length; i += 1) {
  list.push(numbers.children[i]);
}

The updated code is at https://jsfiddle.net/0azkL7s9/2/

How old are the browsers that you plan to support?

1 Like

I am using IE 11 on Windows. But yes, I want to support the most current.

That code does work in IE 11. But by using that code is the randomization better in the first one?

Also, I replaced the li tag with the images tag. I wrapped the ul in a tag and there is a little offset from center. This that correctable?

Also, on refresh after the initial page load, the images seem to have a bounce (1 2) effect on refresh where the first image which is in position 4 goes to position 1 and then bounces down to another position. Is that normal?

Fixed that with replacing ul with div tag.

There is no difference in the randomization.

It is, but that tends to involve CSS which is something that us JavaScript people are not experts at. I recommend the people in our CSS forum for when dealing with CSS issues.

If you want no bounce effect, then using server-side code to set the order of the images before it gets loaded by the browser, is the best solution. The people in our php forum can best help with that.

1 Like

All is well, I am okay with the bounce, just wanted to be sure that would be normal or expected.

Thank you very much for the JS code and I appreciate your help. You know your stuff well!

One last thing for my understanding…

        list.sort(function (a, b) {
            return -1 + Math.random() * 3; // -1, 0, or 1
        });

What is the significance of the -1 and the *3?

Should I change that if I want a different result in the randomization of numbers?

Thanks

Sorting is based on whether the returned value is greater or less than 0.

For example, when sorting numbers you return a-b. A positive value means that a is greater than b and they should be switched, a value of 0 means that they are the same, and a negative value says that a is less than b so they should remain as they are.

We are using the sort method to randomize the values by returning random numbers both above and below zero.
-1 is the number below zero. Adding on 0, 1, or 2, gives us a returned value of -1, 0, or 1
To get a random number between 0 and 2, we need to multiple the random value by 3 and floor it, to get a number between 0 and 2.

Another simpler approach is to just subtract 0.5 from the random value instead, giving us values from -0.5 to 0.499999

        list.sort(function (a, b) {
            return Math.random() - 0.5;
        });
1 Like

If using this, would the result be different or does it depend on how many images I have. Let’s say I have 3, put change to 5 and then later want 10 images running down the page. Is this one better or the first one? Or should I change methods depending on the number of images? The goal is to give each image as close to equal value in terms of position up and down the page upon refresh.

No, the result will be the same. There is still a 50/50 chance of it returning a number either below or above 0, to randomize the list.

1 Like

Thanks!

Returning a random value from sort is not a fully random way of randoming the values in the array.
Here’s why Fisher-Yates (Knuth) Shuffle is an algorithm that every developer should know

The knuth shuffle is the most well known way to properly randomize a list.

function knuthShuffle(arr) {
    var rand, temp, i;
 
    for (i = arr.length - 1; i > 0; i -= 1) {
        rand = Math.floor((i + 1) * Math.random());//get random between zero and i (inclusive)
        temp = arr[rand];//swap i and the zero-indexed number
        arr[rand] = arr[i];
        arr[i] = temp;
    }
    return arr;
}

We can use that in the code example instead.

/* list.sort(function (a, b) {
  return Math.random() - 0.5;
});*/

list = knuthShuffle(list);

The updated code using this improved randomization is at https://jsfiddle.net/0azkL7s9/3/

2 Likes

Thank you for that, I appreciate it.