Objeto: criação de uma página de animes com conteúdo fixo e modificá-la para que o conteúdo seja obtido a partir de uma API pública
Principais termos técnicos abordados ou necessários: JavaScript, fetch(), map(), json(), async, await, CSS, HTML input/a/div/table/ onclick/event, CSS
Requisitos para as instruções funcionarem: nenhum em especial
Requisitos para compreensão das instruções: noções bem básicas de programação JavaScript e HTML
Como ler esse texto: instruções, dentro dos passos descritos e que requerem ação sua no computador, estarão escritas em cor azul. Comentários sobre os passos estarão em fonte normal, cor preta. Comandos, código-fonte, termos técnicos ou configuração explícita, estarão com fonte diferenciada.
Observação: eventuais instruções de terminal serão comandos Linux. Adapte caso esteja usando outro sistema operacional
Faremos uma página HTML de animes, mostrando algumas informações básicas disponíveis, estaticamente, num vetor de objetos JavaScript.
Os diversos exercícios que compõem o mini-projeto vão guiar no sentido de deixar a página mais amigável ao usuário e também no sentido de ir buscar informações na Internet em vez de usar informações fixas em código JavaScript. As questões estão em ordem gradativa de complexidade, é aconselhável que sejam feitam na ordem proposta.
Leiam com atenção o seguinte código e salvem-no como um arquivo intitulado index.html (podem escolher outro nome, desde que mantenham a extensão)
Leiam com atenção o seguinte código e salvem-no como um arquivo intitulado index.html (podem escolher outro nome, desde que mantenham a extensão)
<html>
<body>
<div style="width: 100%; overflow: hidden;">
<div id="tabela" style="width: 400px; float: left;"> Left </div>
<div id="imagem" style="margin-left: 420px;"> </div>
</div>
<script>
var animes = [
{
url: "https://myanimelist.net/anime/1535/Death_Note",
image_url: "https://cdn.myanimelist.net/images/anime/9/9453.jpg?s=b89e80691ac5cc0610847ccbe0b8424a",
title: "Death Note",
score: 8.63,
start_date: "2006-10-04T00:00:00+00:00",
},
{
url: "https://myanimelist.net/anime/28223/Death_Parade",
image_url: "https://cdn.myanimelist.net/images/anime/5/71553.jpg?s=68833377dab9077cd7847c91eec46f08",
title: "Death Parade",
score: 8.18,
start_date: "2015-01-10T00:00:00+00:00",
},
{
url: "https://myanimelist.net/anime/14353/Death_Billiards",
image_url: "https://cdn.myanimelist.net/images/anime/11/48721.jpg?s=4728f1efeabefb313634e64ac91f514b",
title: "Death Billiards",
score: 7.91,
start_date: "2013-03-02T00:00:00+00:00",
}
]
function tabelaAnimes(){
return animes.map(f => `<div>${f.title} - ${f.start_date} - <a href="#" onclick="carregarImagem(event,'${f.image_url}')">Carregar</a> </div>`)
}
//isso é uma função...
const carregarImagem = (event, url) => {
event.preventDefault()
document.getElementById("imagem").innerHTML = `<img src="${url}" width="200px"/>`
}
document.getElementById("tabela").innerHTML = `Titulo - Ano - Imagem<br/> ${tabelaAnimes().join('\n')}`;
</script>
</body>
</html>
Dêem 2 cliques no arquivo para abrir o arquivo index.html no navegador
Essencialmente, a página está montando uma "tabela", bem rudimentar...
A montagem é feita com as informações dos animes que estão na variável JavaScript animes e a função que "monta" a função tabelaAnimes() "transforma" as informações em HTML. Quem de fato põe a tabela montada na página é a linha document.getElementById("tabela").innerHTML = `Titulo - Ano - Imagem<br/> ${tabelaAnimes().join('\n')}`
Além disso, cada clique em Carregar renderiza uma imagem ao lado das informações dos animes, o que é estabelecido no código <a href="#" onclick="carregarImagem(event,'${f.image_url}')">Carregar</a> , que chama a função carregarImagem, que por sua vez faz o "trabalho sujo" de carregar uma imagem num pedaço específico da página.
Os dados da página são, portanto, estáticos, pois estão todos "hardcoded" no código-fonte da página. Além disso, há informações do vetor animes que não estão sendo utilizadas e nossa "tabela" está bem "feinha". Vamos trabalhar em cima dessas deficiências.
Antes de começarmos os trabalhos emocionantes, vamos a algumas possíveis dúvidas iniciais:
Professor, de onde djabo vem aquele event na expressão `<div>${f.title} - ${f.start_date} - <a href="#" onclick="carregarImagem(event,'${f.image_url}')">Carregar</a> </div>` ???
Aquele event é, digamos, presente do navegador. É um objeto que estará sempre disponível para scripts em propriedades que representem eventos (onclick, onmouseover etc) e tem métodos e atributos que descrevem o evento ocorrido (no caso, um clique).
E aquele # no <a href="#" ...> ? É uma hashtag para as redes sociais, é?
Não. Aquele # é porque não queremos que o link abra alguma página específica antes do clique ser processado, queremos que o código JavaScript "decida" o que deve ser feito.
E o event.preventDefault() lá em carregarImagem???
Ao pé da letra, essa linha evita que o comportamento default do evento seja executado pelo navegador. Nesse caso, o comportamento default de um clique num link seria o de carregar a página escrita no atributo href. Não é isso que queremos, queremos que o código JavaScript decida as coisas, independentemente de termos empurrado um # lá no href. O código JavaScript comanda.
E eu não podia apenas dar um return false na função carregarImagem que vez de usar o objeto event?
Podia. Podia até fazer as duas coisas. Mas o preventDefault() é mais "moderninho", dê preferência a ele.
1) O ano está nitidamente num formato ruim para visualização. Modifique a página para mostrar apenas o ano ou, ao menos, a data completa num formato mais amigável
- Dica: pesquise javascript date parse format
2) Há informações que constam no vetor animes e que podem ser utilizadas para melhorar a página. Acrescente a pontuação de avaliação do anime (score) à tabela e faça com que o clique em um título específico abra uma página numa nova janela - o link para esta página está disponível na propriedade url (disponível em cada um dos objetos que constam no vetor animes)
3) Torne essa tabela mais "bonitinha", com cabeçalho, cores alternadas nas linhas (ou ao estilo que você achar melhor)
- Dica: Pesquise na Internet por fancy html table examples
4) Faça ordenar-se a tabela conformemente, de acordo com cliques nos cabeçalhos título, ano e score
5) Modifique o item anterior para que se possa ordenar crescente e decrescentemente. Exemplo: primeiro clique em score ordena por score em ordem crescente, o segundo clique em score ordena por score em ordem decrescente SE a tabela estiver ordenada por score em ordem crescente
6) Acrescente um campo de formulário antes da tabela, com um link "Pesquisar" logo ao lado
- pesquise html text field ou html input types
7) Agora dê uma olhada neste link
https://api.jikan.moe/v3/search/anime?q=death
Ele não carrega uma página HTML, como muitos links que a gente conhece. Carrega, sim, um "bicho" bem parecido com o conteúdo daquele vetor animes de nosso código JavaScript. É porque esse tipo de link (para uma API) não foi concebido para prover informações diretamente às pessoas, mas para prover informações (dados, se vocês preferirem) a programas de computador. Esses programas que transformem esses dados/informações em algo intelegível para um usuário comum.
Ora, nosso código JavaScript é um programa de computador. Assim, para dar um pouco de emoção, vamos fazer com que nosso código, em vez de ter objetos fixos, vá buscá-los no link https://api.jikan.moe/v3/search/anime?q=death
- Dica: pesquise por JavaScript fetch examples
8) Percebam a formação do link https://api.jikan.moe/v3/search/anime?q=death. Copiem e colem no navegador, trocando o death do link por outro termo, naruto, por exemplo, e vejam que a api nos retorna resultados completamente diferentes. Nossa tarefa agora é formar esse link de acordo com o valor digitado pelo usuário no campo de texto que foi implementado na questão 6. Quando o link Pesquisar for acionado, nosso programa deve ir buscar as informações corretas e exibi-las devidamente na tabela bonitinha
9) Pode demorar um pouco até essas informações chegarem ao nosso código javascript após a pesquisa do usuário, pois estamos indo buscá-la num site remoto, que funciona como base de dados para nossa página. Sinalize para o usuário que os dados estão sendo carregados
10) Cereja do bolo. Não realize a pesquisa caso menos de 3 caracteres tenham sido digitados pelo usuário (mostre uma mensagem de erro bonitinha). Além disso, evite novos cliques enquanto os dados de uma requisição estverem sendo carregados
11) Vá além da cereja: pesquise por best free public apis na Internet, encontre alguma api de seu interesse e faça uma nova página com os conhecimentos trabalhados neste mini-projeto