유데미에서 Brad Traversy의 20 Web Projects With Vanilla JavaScript
를 하나씩 직접 코딩해보면서 정리하기 위한 글이다.
데모 페이지
vanillawebprojects.com/projects/lyrics-search/
코드 링크
github.com/rshak8912/20-Web-Projects
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css" />
<title>가사 검색</title>
</head>
<body>
<header>
<h1>가사 검색</h1>
<form id="form">
<input type="text" id="search" placeholder="Enter artist or song name..."/>
<button>Search</button>
</form>
</header>
<div id="result" class="container">
<p>Results will be displayed here</p>
</div>
<div id="more" class="container centered"></div>
<script src="script.js"></script>
</body>
</html>
style.css
* {
box-sizing: border-box;
}
body {
background-color: #fff;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
}
button {
cursor: pointer;
}
button:active {
transform: scale(0.95);
}
input:focus,
button:focus {
outline: none;
}
header {
background-image: url('https://images.unsplash.com/photo-1510915361894-db8b60106cb1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100px 0;
position: relative;
}
header::after {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
header * {
z-index: 1;
}
header h1 {
margin: 0 0 30px;
}
form {
position: relative;
width: 500px;
max-width: 100%;
}
form input {
border: 0;
border-radius: 50px;
font-size: 16px;
padding: 15px 30px;
width: 100%;
}
form button {
position: absolute;
top: 2px;
right: 2px;
background-color: #e056fd;
border: 0;
border-radius: 50px;
color: #fff;
font-size: 16px;
padding: 13px 30px;
}
.btn {
background-color: #8d56fd;
border: 0;
border-radius: 10px;
color: #fff;
padding: 4px 10px;
}
ul.songs {
list-style-type: none;
padding: 0;
}
ul.songs li {
display: flex;
align-items: center;
justify-content: space-between;
margin: 10px 0;
}
.container {
margin: 30px auto;
max-width: 100%;
width: 500px;
}
.container h2 {
font-weight: 300;
}
.container p {
text-align: center;
}
.centered {
display: flex;
justify-content: center;
}
.centered button {
transform: scale(1.3);
margin: 15px;
}
script.js
const form = document.getElementById('form');
const search = document.getElementById('search');
const result = document.getElementById('result');
const more = document.getElementById('more');
const apiURL = 'https://api.lyrics.ovh';
async function searchSongs(term) {
const res = await fetch(`${apiURL}/suggest/${term}`);
const data = await res.json();
showData(data);
}
function showData(data) {
result.innerHTML = `
<ul class="songs">
${data.data
.map(
song => `<li>
<span><strong>${song.artist.name}</strong> - ${song.title}</span>
<button class="btn" data-artist="${song.artist.name}" data-songtitle="${song.title}">Get Lyrics</button>
</li>`
)
.join('')}
</ul>
`;
if (data.prev || data.next) {
more.innerHTML = `
${
data.prev
? `<button class="btn" onclick="getMoreSongs('${data.prev}')">Prev</button>`
: ''
}
${
data.next
? `<button class="btn" onclick="getMoreSongs('${data.next}')">Next</button>`
: ''
}
`;
} else {
more.innerHTML = '';
}
}
async function getMoreSongs(url) {
const res = await fetch(`https://cors-anywhere.herokuapp.com/${url}`);
const data = await res.json();
showData(data);
}
async function getLyrics(artist, songTitle) {
const res = await fetch(`${apiURL}/v1/${artist}/${songTitle}`);
const data = await res.json();
if (data.error) {
result.innerHTML = data.error;
} else {
const lyrics = data.lyrics.replace(/(\r\n|\r|\n)/g, '<br>');
result.innerHTML = `
<h2><strong>${artist}</strong> - ${songTitle}</h2>
<span>${lyrics}</span>
`;
}
more.innerHTML = '';
}
form.addEventListener('submit', e => {
e.preventDefault();
const searchTerm = search.value.trim();
if (!searchTerm) {
alert('Please type in a search term');
} else {
searchSongs(searchTerm);
}
});
result.addEventListener('click', e => {
const clickedEl = e.target;
if (clickedEl.tagName === 'BUTTON') {
const artist = clickedEl.getAttribute('data-artist');
const songTitle = clickedEl.getAttribute('data-songtitle');
getLyrics(artist, songTitle);
}
});
강의를 통해 배운 점(생각, 내용 정리)
- 외부 api를 async 방식으로 호출하여 바인딩 하는 법을 배울 수 있었음
'HTML&CSS&Javascript' 카테고리의 다른 글
[Udemy]20 Web Projects With Vanilla JavaScript -Project#17 (0) | 2021.01.01 |
---|---|
[Udemy]20 Web Projects With Vanilla JavaScript -Project#16 (0) | 2021.01.01 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#14 (0) | 2021.01.01 |
[Udemy]20 Web Projects With Vanilla JavaScript -Project#13 (0) | 2021.01.01 |
자바스크립트 화살표 함수 주의사항 (0) | 2020.12.30 |