What is the easiest way to classify DOM elements using pure Javascript?

Asked

Viewed 74 times

1

How can I classify elements in the DOM using Pure Javascript, to be more clear, we assume that we have a static products page in addition to the products have a field to sort them by price.

body {
    text-align: center
}
select {
    border: 0;
    font-family: sans-serif !important;
    padding: 4px;
    text-transform: uppercase;
    margin-bottom: 10px;
}
.clearfix {
    overflow: auto;
}
.produtos {
    display: block;
    margin: 0 auto;
    width: 90%;
}
.produtos .item {
    float: left;
    margin-right: 1%;
    width: 24%;
}
.produtos .item:nth-child(4n+0) {
    margin-right: 0;
}
.produtos .item h2 {
    font-family: sans-serif;
    font-size: 1.5em;
    margin: 0;
    padding: 0;
}
.produtos .item h3 {
    font-family: sans-serif;
    font-size: 1em;
    font-weight: 300;
}
<select>
    <option>Ordenar por:</option>
    <option value="maior_preco">Maior Preço</option>
    <option value="menor_preco">Menor Preço</option>
</select>

<div class="produtos clearfix">
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 04</h2>
        <h3>R$ 1.564,00</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 07</h2>
        <h3>R$ 322,00</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 01</h2>
        <h3>R$ 10,99</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 03</h2>
        <h3>R$ 153,99</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 06</h2>
        <h3>R$ 2,00</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 08</h2>
        <h3>R$ 500,00</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 05</h2>
        <h3>R$ 2.999,99</h3>
    </div>
    <div class="item">
        <img src="http://via.placeholder.com/300x150" />
        <h2>Produto 02</h2>
        <h3>R$ 768,99</h3>
    </div>
</div>

2 answers

1

Assuming you have an array of built products, which are the ones shown on the page, you can use the function Sort to apply an ordering by any criterion you wish. This function receives a comparison function with the comparison rules between each element.

Considering products with the following structure:

{
    imagem: string,
    nome: string,
    preco: double
}

We can order from highest price to lowest with:

produtos.sort(function(a,b){
  if (a.preco > b.preco) {
    return -1;
  }
  else if (b.preco > a.preco) {
    return 1;
  }
  else {
    return 0;
  }
});

Recalling that the sort takes as a parameter the 2 elements to be compared, in this example the a and the b, and return:

  • < 0 if the a to stay before the b
  • > 0 if the a to stay after the b
  • 0 keep them both in the order they’re in

Another much more simplified and compact way to achieve the same is:

produtos.sort((a,b) => b.preco - a.preco);

That not only get returns through subtraction, but use a Arrow Function instead of a normal function. And for ordering the lowest price just reverse the comparison logic:

produtos.sort((a,b) => a.preco - b.preco);

See your code working with this principle:

let produtos = [
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 04",
    "preco":1564
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 07",
    "preco":322
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 01",
    "preco":10.99
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 03",
    "preco":153.99
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 06",
    "preco":2
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 08",
    "preco":500
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 05",
    "preco":2999.99
  },
  {
    "imagem":"http://via.placeholder.com/300x150",
    "nome":"Produto 02",
    "preco":768.99
  }
];

function mostrarProdutos(){
  let novoHtml = "";
  
  for (let i = 0; i < produtos.length; ++i){
    novoHtml += `<div class="item">
                    <img src="${produtos[i].imagem}" />
                    <h2>${produtos[i].nome}</h2>
                    <h3>${produtos[i].preco.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' })}</h3>
                </div>`;
  }
  
  document.querySelector(".produtos").innerHTML = novoHtml;
}

const selectOrdenacao = document.querySelector("select");

selectOrdenacao.addEventListener("change", function(){
  if (selectOrdenacao.value == "maior_preco"){
    produtos.sort((a,b) => b.preco - a.preco);
  }
  else if (selectOrdenacao.value == "menor_preco"){
    produtos.sort((a,b) => a.preco - b.preco);
  }
  mostrarProdutos();
});

mostrarProdutos();
body {
    text-align: center
}
select {
    border: 0;
    font-family: sans-serif !important;
    padding: 4px;
    text-transform: uppercase;
    margin-bottom: 10px;
}
.clearfix {
    overflow: auto;
}
.produtos {
    display: block;
    margin: 0 auto;
    width: 90%;
}
.produtos .item {
    float: left;
    margin-right: 1%;
    width: 24%;
}
.produtos .item:nth-child(4n+0) {
    margin-right: 0;
}
.produtos .item h2 {
    font-family: sans-serif;
    font-size: 1.5em;
    margin: 0;
    padding: 0;
}
.produtos .item h3 {
    font-family: sans-serif;
    font-size: 1em;
    font-weight: 300;
}
<select>
    <option>Ordenar por:</option>
    <option value="maior_preco">Maior Preço</option>
    <option value="menor_preco">Menor Preço</option>
</select>

<div class="produtos clearfix">
    
</div>

The function mostrarProdutos builds all html that the <div class="produtos clearfix"> had statically based on the product array and applies it through the property innerHTML.

Thus in the change of <select> just change the order of the elements in the array produtos based on the chosen value and recall the function mostrarProdutos.

1

Really sort is the easiest way, but to apply directly to DOM, without changing the structure, it is necessary to apply a regular expression and format the value so that it can be treated in the function, example...

function ordenar() {

let op = document.getElementById("ord").value;
let itens = document.querySelectorAll('.item');
let itensNV = [];

function mpreco(a,b) {
     return parseFloat(a.preco.replace(/R\$|\.|\,|\s/g, "")) < parseFloat(b.preco.replace(/R\$|\.|\,|\s/g, "")) ? -1 : 1; }
               

function mapreco(a,b) {
     return parseInt(a.preco.replace(/R\$|\.|\,|\s/g, "")) > parseInt(b.preco.replace(/R\$|\.|\,|\s/g, "")) ? -1 : 1; }
              

for(let i = 0; i < itens.length; i++) {
	let content = {
		html : itens[i],
        preco : itens[i].children[2].textContent
	}
    itensNV.push(content);
}

switch(op) {
      case 'maior_preco':
			itensNV = itensNV.sort(mapreco);
      break;
      
      case 'menor_preco':
			itensNV = itensNV.sort(mpreco);
      break;
}

document.querySelector('.produtos').innerHTML = '';

for(let i = 0; i < itensNV.length; i++)
   document.querySelector('.produtos').appendChild(itensNV[i].html);

}
    body {
        text-align: center
    }
    select {
        border: 0;
        font-family: sans-serif !important;
        padding: 4px;
        text-transform: uppercase;
        margin-bottom: 10px;
    }
    .clearfix {
        overflow: auto;
    }
    .produtos {
        display: block;
        margin: 0 auto;
        width: 90%;
    }
    .produtos .item {
        float: left;
        margin-right: 1%;
        width: 24%;
    }
    .produtos .item:nth-child(4n+0) {
        margin-right: 0;
    }
    .produtos .item h2 {
        font-family: sans-serif;
        font-size: 1.5em;
        margin: 0;
        padding: 0;
    }
    .produtos .item h3 {
        font-family: sans-serif;
        font-size: 1em;
        font-weight: 300;
    }
<select onchange="ordenar()" id="ord">
        <option>Ordenar por:</option>
        <option value="maior_preco">Maior Preço</option>
        <option value="menor_preco">Menor Preço</option>
    </select>

    <div class="produtos clearfix">
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 04</h2>
            <h3>R$ 1.564,00</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 07</h2>
            <h3>R$ 322,00</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 01</h2>
            <h3>R$ 10,99</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 03</h2>
            <h3>R$ 153,99</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 06</h2>
            <h3>R$ 2,00</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 08</h2>
            <h3>R$ 500,00</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 05</h2>
            <h3>R$ 2.999,99</h3>
        </div>
        <div class="item">
            <img src="http://via.placeholder.com/300x150" />
            <h2>Produto 02</h2>
            <h3>R$ 768,99</h3>
        </div>
    </div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.