今天要做的一个小demo可能作用不大,纯当练习,先看效果:
其实是调用的一个网站的api。
话不多说,先看代码:
首先是html部分:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Movie App</title>
</head>
<body>
<header>
<form id="form">
<input type="text" id="search" class="search" placeholder="Search">
</form>
</header>
<main id="main"></main>
<script src="script.js"></script>
</body>
</html>
这里面没啥,就基本布局,搜索框,表单,和main部分,就是存放电影的部分。
再来看css部分:
:root{
--primary-color: #22254b;
--secondary-color: #373b69;
}
* {
box-sizing: border-box;
}
body{
background-color: var(--primary-color);
margin: 0;
}
header{
padding: 1rem;
display: flex;
/* 从行尾开始排列 */
justify-content: flex-end;
background-color: var(--secondary-color);
}
.search{
background-color: transparent;
border: 2px solid var(--primary-color);
border-radius: 50px;
font-family: inherit;
/* 1rem默认情况下是16px */
font-size: 1rem;
padding: 0.5rem 1rem;
color: #fff;
}
.search::placeholder{
color: #7378c5;
}
.search:focus{
outline: none;
background-color: var(--primary-color);
}
/* 电影区 */
main{
display: flex;
flex-wrap: wrap;
flex:1;
}
.movie{
width: 300px;
margin: 1rem;
background-color: var(--secondary-color);
box-shadow: 0 4px 5px rgba(0,0,0,0.2);
position: relative;
overflow: hidden;
border-radius: 3px;
}
/* 电影图片 */
.movie img{
width: 100%;
}
/* 电影信息 */
.movie-info{
color: #eee;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5rem 1rem 1rem;
/* 字符间距 */
letter-spacing: 0.5px;
}
/* 电影标题 */
.movie-info h3{
margin-top: 0;
}
/* 评分 */
.movie-info span{
background-color: var(--primary-color);
padding: 0.25rem 0.5rem;
border-radius: 3px;
font-weight: bold;
}
/* 评分颜色 */
.movie-info span.green{
color: lightgreen;
}
.movie-info span.orange{
color: orange;
}
.movie-info span.red{
color: red;
}
/* 电影概述 */
.overview{
background-color: #fff;
padding: 2rem;
position: absolute;
left: 0;
bottom: 0;
right: 0;
max-height: 100%;
transform: translateY(101%);
transition: transform 0.3s ease-in;
}
/* 鼠标悬停弹出电影概述 */
.movie:hover .overview{
transform: translateY(0);
}
这里也没啥,哪一块是哪一块的样式也给大家写好注释了,大家自己看看,不懂的话评论区留言。
再来看JavaScript部分:
这一部分主要就是通过fetch异步获取api提供的数据,然后书写显示电影以及获取电影评分,以及搜索的api调用的方法,并不复杂,需要关注的只有中间显示电影部分的自定义节点以及节点上树,通过模板字符串来动态渲染页面。
// 需要注册https://www.themoviedb.org/获取api
const API_URL = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3fd2be6f0c70a2a598f084ddfb75487c&page=1'
const IMG_PATH = 'https://image.tmdb.org/t/p/w1280'
const SEARCH_API = 'https://api.themoviedb.org/3/search/movie?api_key=3fd2be6f0c70a2a598f084ddfb75487c&query="'
const main = document.getElementById('main')
const form = document.getElementById('form')
const search = document.getElementById('search')
// 获取电影
getMovies(API_URL)
// 异步获取
async function getMovies(url) {
const res = await fetch(url)
// 获取json类型的数据
const data = await res.json()
showMovies(data.results)
}
// 显示电影
function showMovies(movies) {
// 先清空main
main.innerHTML = ''
movies.forEach((movie) => {
const { title, poster_path, vote_average, overview } = movie
// 自定义节点以及上树
const movieEl = document.createElement('div')
movieEl.classList.add('movie')
movieEl.innerHTML = `
<img src="${IMG_PATH + poster_path}" alt="${title}">
<div class="movie-info">
<h3>${title}</h3>
<span class="${getClassByRate(vote_average)}">${vote_average}</span>
</div>
<div class="overview">
<h3>Overview</h3>
${overview}
</div>
`
main.appendChild(movieEl)
})
}
// 获取电影分数方法
function getClassByRate(vote) {
if(vote >= 8) {
return 'green'
} else if(vote >= 5) {
return 'orange'
} else {
return 'red'
}
}
form.addEventListener('submit', (e) => {
e.preventDefault()
const searchTerm = search.value
if(searchTerm && searchTerm !== '') {
// 调用搜索api以及拿到你要搜索的关键字
getMovies(SEARCH_API + searchTerm)
// 将搜索框清空
search.value = ''
} else {
// 重载页面
window.location.reload()
}
})
今天的小demo就到这里了,大家可以作为一个小练习,大家一起加油!