3

I want to sort an array of HTML elements. I want to sort them by the css left property value. That means that the element with the lowest left value is the first element of the array that I want to sort and the element with the highest left value is the last element of the array that I want to sort.

If somebody gives me an answer, please don't give me an answer with jquery, because I don't know anything in jquery.

const games = document.querySelectorAll('.games');

games.sort((a, b) => {
  return parseInt(window.getComputedStyle(a).getPropertyValue('left')) - parseInt(window.getComputedStyle(b).getPropertyValue('left'))
})
.games {
  position: absolute;
  transform: scale(1);
  transition: left 0.4s ease;
  width: 20vw;
  height: 20vw;
  border-radius: 2.5vw;
  background-color: white;
  display: flex;
  justify-content: center;
}

.games:nth-of-type(1) {
  left: 6.5vw;
}

.games:nth-of-type(2) {
  left: 40;
}

.games:nth-of-type(3) {
  left: calc(100vw - 6.5vw - 20vw);
  /* same position if you write: right: 6.5vw*/
}
<div class="games"></div>
<div class="games"></div>
<div class="games"></div>

2
  • I made you a snippet, I had to add some brackets. Commented Mar 26, 2022 at 8:02
  • I addition to the answer provided, I suggest you always use a radix in your parseInt method - parseInt(num, 10) like so, and always check it is a number - ie !Number.isNaN() before doing calculation on it. left may not exist for example. Commented Mar 26, 2022 at 8:08

1 Answer 1

2

You were missing brackets and you need a spread to make it a sortable array.

Modern browsers (early EDGE excepted) can do a forEach on a querySelectorAll nodeList, but to map, filter and sort, you need to convert to array.

Here is a more concise version. Note I use parseFloat to get rid of the units

const games = [...document.querySelectorAll('.games')]; // has to be an array to sort it
const getProp = (elem,prop) => window.getComputedStyle(elem).getPropertyValue(prop);
console.log(games)
games.sort((a, b) => parseFloat(getProp(a,'left')) - parseFloat(getProp(b,'left')));

// debug

games.forEach(game => game.textContent += ': ' + getProp(game,'left'))

console.log(games)
.games {
  position: absolute;
  transform: scale(1);
  transition: left 0.4s ease;
  width: 20vw;
  height: 20vw;
  border-radius: 2.5vw;
  background-color: white;
  display: flex;
  justify-content: center;
}

.games:nth-of-type(1) {
  left: 6.5vw;
}

.games:nth-of-type(2) {
  left: 40;
}

.games:nth-of-type(3) {
  left: calc(100vw - 6.5vw - 20vw);
  /* same position if you write: right: 6.5vw*/
}
<div class="games">1</div>
<div class="games">2</div>
<div class="games">3</div>

Sign up to request clarification or add additional context in comments.

5 Comments

left can't be unit-less (except for 0), so their comparator is also broken. (I guess they'd be better using .offsetLeft or alike)
@Kaiido and it is even a float. Updated to use parseFloat
Now I have no more errors in the console, but the array doesn't sort correctly. I don't know why it doesn't sort correctly, but I think you can help me, because for me it seemed so.
It sorts. If it does not sort correctly, then it is the nth-of-type you need to look at
See my update to see the left positions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.