50天50个前端小项目(纯html+css+js)第十七天(电影搜索推荐页)

今天要做的一个小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就到这里了,大家可以作为一个小练习,大家一起加油!

项目gitee地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mzldustu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值