<template>
<option>
<img>
<span></span>
</option>
</template>
<select>
<button>
<selectedcontent></selectedcontent>
</button>
<div id="container" class="container"></div>
</select>
<dl>
<dt>name</dt>
<dd id="name"></dd>
</dl>
<dl>
<dt>genus</dt>
<dd id="genus"></dd>
</dl>
<dl>
<dt>type</dt>
<dd id="type"></dd>
</dl>
<dl>
<dt>height</dt>
<dd id="height"></dd>
</dl>
<dl>
<dt>weight</dt>
<dd id="weight"></dd>
</dl>
<dl>
<dt>cry</dt>
<dd>
<audio id="cry" controls></audio>
</dd>
</dl>
:root {
--radius: 0.5em;
--space: 1em;
}
select, ::picker(select) {
appearance: base-select;
border-radius: var(--radius);
}
select::picker-icon {
display: none;
}
select:open {
background-color: lightgray;
}
selectedcontent {
display: inline-flex;
flex-direction: column;
img {
width: 4em;
}
}
option::checkmark {
content: attr(data-type);
}
option:checked {
background-color: ivory;
}
.container {
display: grid;
grid-template: 1fr 1fr / 1fr 1fr 1fr;
padding: var(--space);
gap: var(--space);
option {
display: inline-flex;
flex-direction: column;
border-radius: var(--radius);
img {
width: 4em;
}
}
}
const POKEMON_API = 'https://pokeapi.co/api/v2/pokemon';
const POKEMON_SPICIES_API = 'https://pokeapi.co/api/v2/pokemon-species';
const IMAGE_PATH = 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork';
const TYPES = {
normal: '🐾',
fire: '🔥',
water: '💧',
electric: '⚡',
grass: '🌿',
ice: '❄️',
fighting: '🥊',
poison: '☠️',
ground: '🌋',
flying: '🦅',
psychic: '🔮',
bug: '🐛',
rock: '🪨',
ghost: '👻',
dragon: '🐉',
dark: '🌑',
steel: '🔩',
fairy: '🧚'
};
async function getPokemons(limit) {
const response = await fetch(`${POKEMON_API}?limit=${limit}`);
const json = await response.json();
return json;
}
async function getPokemon(name) {
const response = await fetch(`${POKEMON_API}/${name}`);
const json = await response.json();
return json;
}
async function getPokemonSpecies(name) {
const response = await fetch(`${POKEMON_SPICIES_API}/${name}`);
const json = await response.json();
return json;
}
window.addEventListener('load', async () => {
const cacheObject = JSON.parse(localStorage.getItem('cache')) ?? {};
const {results: pokemons} = await getPokemons(151);
const template = document.querySelector('template');
const select = document.querySelector('select');
const container = select.querySelector('#container');
const name = document.querySelector('#name');
const genus = document.querySelector('#genus');
const type = document.querySelector('#type');
const height = document.querySelector('#height');
const weight = document.querySelector('#weight');
const cry = document.querySelector('#cry');
pokemons.forEach((pokemon, index) => {
const option = document.importNode(template.content, true);
const img = option.querySelector('img');
img.src = `${IMAGE_PATH}/${index + 1}.png`;
img.alt = pokemon.name;
const span = option.querySelector('span');
span.textContent = pokemon.name;
container.append(option);
});
select.addEventListener('change', async e => {
const {language} = window.navigator;
const data = cacheObject[select.value] ?? {
await getPokemon(select.value),
await getPokemonSpecies(select.value)
};
if (!cacheObject[select.value]) {
console.debug(`data is not cached: ${select.value}`);
const {names, genera, types} = data;
cacheObject[select.value] = {
names,
genera,
types
};
try {
localStorage.setItem('cache', JSON.stringify(cacheObject));
} catch (error) {
console.error(error);
}
}
name.textContent = data.names.find(item => item.language.name === language)?.name ?? pokemon.name;
genus.textContent = data.genera.find(item => item.language.name === language)?.genus ?? '';
type.textContent = data.types.map(({type}) => TYPES[type.name]).join(' ');
cry.src = data.cries.latest;
height.textContent = `${data.height / 10}m`;
weight.textContent = `${data.weight / 10}kg`;
});
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.