Node App:如何创建 Netflix 克隆版。使用 HTML、CSS 和 JS 实现 Netflix 克隆。视频教程代码文章,你可能会觉得有用 AWS GenAI LIVE!

2025-06-07

Node App:如何创建 Netflix 克隆版。使用 HTML、CSS、JS 进行 Netflix 克隆。

视频教程

代码

您可能觉得有用的文章

AWS GenAI 直播!

大家好,今天我们将学习如何仅使用 HTML、CSS 和 JS 轻松创建 Netflix 克隆版本,无需其他库。我们还将使用 TMDB API 从其数据库中获取真实数据。

Netflix Clone,我们日常生活中都使用Netflix。如果你刚开始接触Web开发,这个项目可以成为你一个很好的练习项目。这个Netflix Clone是一个动态网站,拥有你进行全栈开发实践所需的一切。它运行在Node.js服务器上,并使用TMDB API处理所有数据。

特征

  1. 看起来与 Netflix 相似。
  2. 动态站点在 Node.js 服务器上运行。
  3. 所有数据均来自 TMDB API。
  4. 专用动态电影信息页面。
  5. 有电影预告片和推荐。
  6. 具有流畅的卡片滑块效果。

捕获-2 (1)

如果您想观看演示或完整的编码教程视频,可以观看下面的教程。

视频教程

如果您能订阅我的 YouTube 频道来支持我,我将不胜感激。

因此,不要浪费更多时间,让我们看看如何编写代码。

代码

由于这是一个 node.js web 应用,我们需要 NPM 和 Node.js 才能启动,因此请确保您的系统中已安装它们。

那么让我们从它的文件夹结构开始吧。

文件夹结构。

这是我们的文件夹结构。

文件夹结构

NPM 初始化

让我们从初始化 NPM 开始。在public文件夹外部,在你的root目录中,打开命令提示符或终端。然后执行。npm init

它会询问你一些详细信息。你可以按 Enter 键获取默认的项目详细信息。执行后,npm init你应该会看到一个package.json文件。

很好,现在安装创建服务器所需的一些库。

安装库

创建package.json文件后。运行此命令。



npm i express.js nodemon


Enter fullscreen mode Exit fullscreen mode

i- 表示安装。
express.js- 是我们创建服务器所需的库。
nodemon- 是一个允许您即使在对服务器进行更改后也能无缝运行服务器的库。

安装完成后,您应该能够在目录node_modules中看到文件夹root

现在package.json用文本编辑器打开文件,并进行一些编辑。

  1. "main"将键上的值更改为"server.js"
    主要的

  2. 从对象中删除"test"cmd 。并添加名为 的新 cmd ,并将其值设置为"scripts""start""nodemon server.js"
    脚本

服务器.js

编辑后在目录中package.json创建 JS 文件server.jsroot

并将其写入server.js



const express = require('express');
const path = require('path');

let initial_path = path.join(__dirname, "public");

let app = express();
app.use(express.static(initial_path));

app.get('/', (req, res) => {
    res.sendFile(path.join(initial_path, "index.html"));
})

app.listen(3000, () => {
    console.log('listening on port 3000......');
})


Enter fullscreen mode Exit fullscreen mode
解释

在顶部,我们使用require方法导入库,以便我们可以在此文件中使用它。我们导入了两个库expresspath

path库用于跟踪路径。

导入库完成后,我们将设置一个app等于 的变量express(),这样所有与服务器相关的功能都可以添加到我们的app变量中。此外,我们还设置了initial_path一个 ,用于保存public文件夹路径。

之后,我们有app.use()一个用作中间件的函数,它express.static()允许我们设置静态目录路径。在本例中,我们将public文件夹设置为静态路径,因为我们的HTML文件就在该文件夹中。

app.get('/')是一个监听器,在本例中,它监听的是指向GET我们根/路径的请求。每当我们收到任何GET请求时/,我们都会向其提供index.html文件。这就是我们res.sendFile()要做的。

我们的最后一块server.jsapp.listen用于添加服务器监听端口的。在本例中,我们将其设置为3000。这样我们的服务器将在 上运行localhost:3000,而不是其他任何端口。

现在,在终端或 cmd 提示符下运行npm start以下命令启动服务器。然后,打开浏览器localhost:3000。您将能够看到index.html文件。

到目前为止,我们已经创建了服务器并成功地将index.html文件提供给/路径。

那么我们来做一些前端工作吧。现在

主页。

因此对于我们主页,我们将使用这些文件index.html,,,,style.csshome.jsapi.jsscroll.js

让我们从index.html文件开始。先输入基本的 HTML 结构。然后是链接style.css文件。首先,我们来创建导航栏。



<!-- navbar -->
<nav class="navbar">
    <img src="img/logo.png" class="logo" alt="">
    <div class="join-box">
        <p class="join-msg">unlimited tv shows & movies</p>
        <button class="btn join-btn">join now</button>
        <button class="btn">sign in</button>
    </div>
</nav>


Enter fullscreen mode Exit fullscreen mode

确保您的服务器正在运行,如果没有,则npm start在您的终端中运行。

输出

导航栏

我将用到的所有 CSS 属性都很容易理解。所以我只会解释 JS 部分。如果您对任何部分有任何疑问,即使是 CSS 部分,也欢迎在讨论中问我。

现在设置导航栏的样式



*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
    width: 100%;
    position: relative;
    background: #181818;
    font-family: 'roboto', sans-serif;
}

.navbar{
    width: 100%;
    height: 60px;
    position: fixed;
    top: 0;
    z-index: 9;
    background: #000;
    padding: 0 2.5vw;
    display: flex;
    align-items: center;
}

.logo{
    height: 60%;
}

.join-box{
    width: fit-content;
    display: flex;
    justify-content: center;
    align-items: center;
    height: auto;
    margin-left: auto;
}

.join-msg{
    color: #fff;
    text-transform: uppercase;
}

.btn{
    border: 1px solid #fff;
    border-radius: 2px;
    background: none;
    color: #fff;
    height: 35px;
    padding: 0 10px;
    margin-left: 10px;
    text-transform: uppercase;
    cursor: pointer;
}

.join-btn{
    background: #dd0e15;
    border-color: #dd0e15;
}


Enter fullscreen mode Exit fullscreen mode
输出

导航栏 2
现在创建电影部分。



<!-- main section -->
<header class="main">
    <h1 class="heading">movies</h1>
    <p class="info">Movies move us like nothing else can, whether they're scary, funny, dramatic, romantic or anywhere in-between. So many titles, so much to experience.</p>
</header>


Enter fullscreen mode Exit fullscreen mode

并设计它



.main{
    position: relative;
    margin-top: 60px;
    width: 100%;
    padding: 40px 2.5vw;
    color: #fff;
}

.heading{
    text-transform: capitalize;
    font-weight: 900;
    font-size: 50px;
}

.info{
    width: 50%;
    font-size: 20px;
    margin-top: 10px;
}


Enter fullscreen mode Exit fullscreen mode

主要-2
我们必须在.main元素内部创建一个电影列表元素,它将保存相同类型的电影。



<div class="movie-list">

    <button class="pre-btn"><img src="img/pre.png" alt=""></button>

    <h1 class="movie-category">Popular movie</h1>

    <div class="movie-container">
        <div class="movie">
            <img src="img/poster.jpg" alt="">
            <p class="movie-title">movie name</p>
        </div>
    </div>

    <button class="nxt-btn"><img src="img/nxt.png" alt=""></button>

</div>


Enter fullscreen mode Exit fullscreen mode

你可以看到,我们创建了它们,pre-btn并且nxt-btn它们之间也包含一个movie-card元素。好吧,我们将使用 JS 创建电影卡片和列表元素,但出于样式方面的考虑,我们在这里只创建了一个卡片。这只是为了方便 CSS 使用。



.movie-list{
    width: 100%;
    height: 250px;
    margin-top: 40px;
    position: relative;
}

.movie-category{
    font-size: 20px;
    font-weight: 500;
    margin-bottom: 20px;
    text-transform: capitalize;
}

.movie-container{
    width: 100%;
    height: 200px;
    display: flex;
    align-items: center;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
}

.movie-container::-webkit-scrollbar{
    display: none;
}

.movie{
    flex: 0 0 auto;
    width: 24%;
    height: 200px;
    text-align: center;
    margin-right: 10px;
    cursor: pointer;
    position: relative;
}

.movie img{
    width: 100%;
    height: 170px;
    object-fit: cover;
}

.movie p{
    text-transform: capitalize;
    height: 20px;
    overflow: hidden;
}

.pre-btn,
.nxt-btn{
    position: absolute;
    height: 200px;
    top: 50%;
    transform: translateY(-50%);
    width: 2.5vw;
    background: #181818;
    border: none;
    outline: none;
    opacity: 0;
}

.pre-btn{
    left: -2.5vw;
}

.nxt-btn{
    right: -2.5vw;
}

.pre-btn img,
.nxt-btn img{
    width: 20px;
    height: 20px;
    object-fit: contain;
}

.nxt-btn:hover,
.pre-btn:hover{
    opacity: 1;
}


Enter fullscreen mode Exit fullscreen mode
输出

捕获-3

一旦我们完成了卡片的造型,我们就可以提交它们。



<header class="main">
    <h1 class="heading">movies</h1>
    <p class="info">Movies move us like nothing else can, whether they're scary, funny, dramatic, romantic or anywhere in-between. So many titles, so much to experience.</p>
    <!-- movie list -->
    <!-- <div class="movie-list">

        <button class="pre-btn"><img src="img/pre.png" alt=""></button>

        <h1 class="movie-category">Popular movie</h1>

        <div class="movie-container">
            <div class="movie">
                <img src="img/poster.jpg" alt="">
                <p class="movie-title">movie name</p>
            </div>
        </div>

        <button class="nxt-btn"><img src="img/nxt.png" alt=""></button>

    </div> -->
</header>


Enter fullscreen mode Exit fullscreen mode

我们的main版块应该看起来像这样。主页部分已经完成了。

现在将所有 JS 文件添加到index.html文件中。因为我们现在需要它们。



<script src="js/api.js"></script>
<script src="js/scroll.js"></script>
<script src="js/home.js"></script>


Enter fullscreen mode Exit fullscreen mode

确保按照完全相同的顺序添加这些文件。

现在前往TMDB 官方网站创建 API 密钥。如果您不知道如何创建,请观看此视频

创建 API 密钥后将其粘贴到api.js文件中

api.js


let api_key = "your api key";


Enter fullscreen mode Exit fullscreen mode

然后前往TMDB 文档。找到以下三个 HTTP 链接。

api.js


let api_key = "your api key";

let img_url = "https://image.tmdb.org/t/p/w500";
let genres_list_http = "https://api.themoviedb.org/3/genre/movie/list?";
let movie_genres_http = "https://api.themoviedb.org/3/discover/movie?";


Enter fullscreen mode Exit fullscreen mode
  1. img_url- 用于获取图片。因为我们会获取电影图片的路径 ID。例如,如果我们获取的图片 ID 为,123则图片 URL 为https://image.tmdb.org/t/p/w500/123
  2. genres_list_http- 用于获取电影类型列表,这样我们就不必手动获取不同类型的电影。
  3. movie_genres_http- 是获取具有相同类型的电影。

完成这些 HTTPS 后,打开home.js文件。

home.js


fetch(genres_list_http + new URLSearchParams({
    api_key: api_key
}))
.then(res => res.json())
.then(data => {
    data.genres.forEach(item => {
        fetchMoviesListByGenres(item.id, item.name);
    })
});


Enter fullscreen mode Exit fullscreen mode
解释

在这里,我们使用了在文件中声明fetch的方法。并用于向链接添加参数。获取 res 后,我们将其转换为 JSON ,转换为 JSON 后,我们得到了获取的数据。在理解我们在做什么之前,首先看一下获取的数据结构。genres_list_httpapi.jsnew URLSearchParamsapi_keyres.json()

捕获-2

这样就理解了数据结构。现在明白了获取 JSON 数据后我们在做什么。



data.genres.forEach(item => {
    fetchMoviesListByGenres(item.id, item.name);
})


Enter fullscreen mode Exit fullscreen mode

由于我们有一个包含各种类型的数组,因此我们使用方法循环遍历每个类型forEach。并在其中调用fetchMoviesListByGenres(id, genres)我们接下来要创建的方法。

现在获取具有不同类型的电影。



const fetchMoviesListByGenres = (id, genres) => {
    fetch(movie_genres_http + new URLSearchParams({
        api_key: api_key,
        with_genres: id,
        page: Math.floor(Math.random() * 3) + 1
    }))
    .then(res => res.json())
    .then(data => {
        makeCategoryElement(`${genres}_movies`, data.results);
    })
    .catch(err =>  console.log(err));
}


Enter fullscreen mode Exit fullscreen mode
解释

在这里我们做同样的事情,我们正在获取数据,但在这种情况下,我们正在发出请求movie_genres_http并添加更多参数。param
with_genres将为我们提供仅具有该类型的电影,例如,如果我们的类型 id 为喜剧电影,那么我们只会得到喜剧电影。param
page将提供我们想要的结果,在这种情况下,我们使用它Math.random()来获取一些随机的电影结果页面。

获取数据后,我们执行相同的res.json()操作将其转换为 JSON。调用makeCategoryElement(category, data)该函数将创建影片类别。同样,如果您愿意,也可以通过控制台记录数据结构。

现在创建电影类别。但在此之前,请main从 HTML 中选择我们的元素。



const main = document.querySelector('.main');


Enter fullscreen mode Exit fullscreen mode


const makeCategoryElement = (category, data) => {
    main.innerHTML += `
    <div class="movie-list">

        <button class="pre-btn"><img src="img/pre.png" alt=""></button>

        <h1 class="movie-category">${category.split("_").join(" ")}</h1>

        <div class="movie-container" id="${category}">

        </div>

        <button class="nxt-btn"><img src="img/nxt.png" alt=""></button>

    </div>
    `;
    makeCards(category, data);
}


Enter fullscreen mode Exit fullscreen mode
解释

在这个函数中,我们有两个参数,一个是category,另一个是data。所以我们函数做的第一件事就是使用 向我们的元素添加一个.movie-list元素。如果你还记得我们在 HTML 文件中创建的代码,但最后注释掉了,请复制并粘贴到这里。确保使用not ,因为我们不想重写它的 HTML。maininnerHTML+==

<h1 class="movie-category">${category.split("_").join(" ")}</h1>
如果你看到这行代码,首先,我们使用了 JS 模板字符串,如果不使用,你将无法像这样写。这里我们有一个h1元素,我们将它的文本设置为我们在函数开始时获取的类别。但我们也在这里执行了一些方法。让我们详细看看它们。

例如,假设类别等于喜剧。

  1. <h1 class="movie-category">${category}</h1>那么输出将是 - comdey_movies。但我们不想,_这就是我们拆分它的原因。
  2. <h1 class="movie-category">${category.split("_")}</h1>那么它将无法工作,因为现在我们有一个数组 ["comedy", "movies"]。这就是为什么要使用join方法来连接数组。
  3. <h1 class="movie-category">${category.split("_").join(" ")}</h1>那么输出将是 - 喜剧电影

我希望你明白这一点。

然后我们为元素设置一个唯一的 ID,movie-container以便稍后添加卡片。最后,我们调用makeCards(category, data)该函数在电影容器元素内创建卡片。

现在创建一张卡片。



const makeCards = (id, data) => {
    const movieContainer = document.getElementById(id);
    data.forEach((item, i) => {

    })
}


Enter fullscreen mode Exit fullscreen mode
解释

在这个函数中,我们使用从上面函数获取的数据,在开始时选择影片容器元素id。之后,我们循环遍历datausingforEach方法。在方法内部,我们检查一些条件。



if(item.backdrop_path == null){
   item.backdrop_path = item.poster_path;
   if(item.backdrop_path == null){
      return;
  }
}


Enter fullscreen mode Exit fullscreen mode

这个条件是检查,如果我们的结果集里没有电影backdrop图片路径,就把它设置poster_path为“否”。别搞砸了。有时 TMDB 电影的数据里没有图片路径,所以我们会检查它。

之后我们有



movieContainer.innerHTML += `
<div class="movie" onclick="location.href = '/${item.id}'">
    <img src="${img_url}${item.backdrop_path}" alt="">
    <p class="movie-title">${item.title}</p>
</div>
`;


Enter fullscreen mode Exit fullscreen mode

这里,我们使用了该innerHTML方法来附加一开始就已经创建好的卡片 HTML 结构。同样,这里我们也使用了模板字符串。如果您看到我们有onclick一个事件到movie-card元素,我们将使用该事件location.href将用户重定向到我们接下来要创建的电影页面。



if(i == data.length - 1){
    setTimeout(() => {
        setupScrolling();
    }, 100);
}


Enter fullscreen mode Exit fullscreen mode

这是检查最后一次施法。卡片创建完成后,我们将运行setupScrolling()函数来设置滑块效果。我们也必须创建这个。

写完这么多 JS 代码,现在我们可以看到输出了,没有任何错误。

输出

捕获

但是我们还没有创建滑块效果写入。对于那个打开的scroll.js文件。

scroll.js


const setupScrolling = () => {
    const conainter = [...document.querySelectorAll('.movie-container')];
    const nxtBtn = [...document.querySelectorAll('.nxt-btn')];
    const preBtn = [...document.querySelectorAll('.pre-btn')];
}


Enter fullscreen mode Exit fullscreen mode
解释

querySelectorAll首先,在这个函数中,我们使用方法选择我们的容器、下一个按钮和上一个按钮。

选择它们后,在函数内部输入以下内容。



conainter.forEach((item, i) => {
    let containerDimensions = item.getBoundingClientRect();
    let containerWidth = containerDimensions.width;
})


Enter fullscreen mode Exit fullscreen mode

这里我们循环遍历每个容器元素。并使用getBoundingClientRect方法获取容器的尺寸。最后将其存储containerDimensions.width(当然,这会给出容器的宽度)到containerWidth

之后在这个 for 循环中添加这个。



nxtBtn[i].addEventListener('click', () => {
    item.scrollLeft += containerWidth;
})

preBtn[i].addEventListener('click', () => {
    item.scrollLeft -= containerWidth;
}


Enter fullscreen mode Exit fullscreen mode

这里我们选择nxtBtn带有preBtn容器索引的元素,并为其添加点击事件。此外,还进行了一些简单的数学运算。

此后我们应该能够获得滑块效果。

我们的主页已经完成。

服务器.js

现在我们需要在关于页面中添加一些代码server.js
在之前输入这些代码app.listen()



app.get('/:id', (req, res) => {
    res.sendFile(path.join(initial_path, "about.html"));
})

app.use((req, res) => {
    res.json("404");
})


Enter fullscreen mode Exit fullscreen mode

这里,我们为路径添加了 GET 请求监听器/:id。这意味着任何前面带有单斜杠的路径都会执行代码。它适用于/123,但不适用于/123/12/1。最后,我们app.use()再次使用 which 作为中间件,这意味着如果请求路径与上述路径不同,则执行此操作。这意味着404消息。

此后,您将能够通过点击电影卡片将自己重定向到电影详细信息页面。

关于页面

让我们创建最后一个页面。为了避免编写大量的 CSS,我们可以使用链接about.css和文件。style.css

然后将导航栏复制粘贴到这里。之后创建 movie-info 元素

关于.html


<!-- movie info -->
<div class="movie-info">
    <div class="movie-detail">
        <h1 class="movie-name">Movie Name</h1>
        <p class="genres">Comedy</p>
        <p class="des">Lorem ipsum dolor sit amet consectetur, adipisicing elit. In commodi incidunt odit inventore suscipit, debitis officia modi exercitationem animi nemo.</p>
        <p class="starring"><span>Starring:</span></p>
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode

并进行造型。



.movie-info{
    width: 100%;
    height: calc(100vh - 60px);
    margin-top: 60px;
    background-size: cover;
    background-repeat: no-repeat;
}

.movie-detail{
    width: 50%;
    height: 100%;
    background: rgb(24, 24, 24);
    background: linear-gradient(90deg, rgba(24, 24, 24, 1), rgba(24, 24, 24, 0) 100%);
    padding: 5vw;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    color: #fff;
}

.movie-name{
    font-size: 30px;
    font-weight: 500;
}

.genres{
    opacity: 0.6;
    margin: 30px 0;
}

.des{
    width: 70%;
    line-height: 20px;
    margin-bottom: 30px;
}

.starring span{
    opacity: 0.6;
}


Enter fullscreen mode Exit fullscreen mode
输出

捕获-4
CSS 完成后,您可以从信息元素中删除所有文本,使其完全为空。



<h1 class="movie-name"></h1>
<p class="genres"></p>
<p class="des"></p>
<p class="starring"><span>Starring:</span></p>


Enter fullscreen mode Exit fullscreen mode

像这样。

现在创建视频推荐。



<div class="trailer-container">
    <h1 class="heading">Video Clip</h1>
    <iframe src="" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>


Enter fullscreen mode Exit fullscreen mode

你应该注意到了iframe。这有点难理解,所以我建议你看一下这个视频预告片,以便更好地理解。Style
It。



.trailer-container,
.recommendations{
    color: #fff;
    padding: 5vw 5vw 0;
}

.heading{
    font-size: 30px;
    font-weight: 300;
    margin-bottom: 20px;
}

iframe{
    width: 400px;
    height: 200px;
}


Enter fullscreen mode Exit fullscreen mode

在输出中,除了电影信息元素和视频剪辑文本外,我们什么也看不到。因为我们的iframe源是空的。

现在创建推荐容器。



<div class="recommendations">
    <h1 class="heading">More Like This</h1>
    <div class="recommendations-container">
        <div class="movie">
            <img src="img/poster.jpg" alt="">
            <p class="movie-title">movie name</p>
        </div>
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS



.recommendations-container{
    width: 100%;
    display: flex;
    flex-wrap: wrap;
}

.movie p{
    position: absolute;
    bottom: 30px;
    width: 100%;
    height: 30px;
    line-height: 30px;
    background: rgba(0, 0, 0, 0.5);
    text-align: center;
    opacity: 0;
}

.movie:hover p{
    opacity: 1;
}


Enter fullscreen mode Exit fullscreen mode
输出

捕获05
我们已经完成了样式设置。您可以对.movie元素进行注释。这与我们在主页中创建的元素相同。

也向此页面添加脚本。记住,添加顺序完全相同。



<script src="js/api.js"></script>
<script src="js/about.js"></script>


Enter fullscreen mode Exit fullscreen mode

现在打开api.js文件。并添加以下内容。



let original_img_url = "https://image.tmdb.org/t/p/original";
let movie_detail_http = "https://api.themoviedb.org/3/movie";


Enter fullscreen mode Exit fullscreen mode

您可以从 TMDB 文档中找到这些 HTTP。
original_img_url- 这是为了获取原始分辨率的电影图像。
movie_detail_http- 这是为了获取特定电影的详细信息。

现在打开about.js。然后写下这个。



let movie_id = location.pathname;


Enter fullscreen mode Exit fullscreen mode

location.pathname将能够从 URL 中提取电影 ID。例如,如果 URL 是,localhost:3000/123则这将返回/123我们的电影 ID。

之后使用相同的fetch方法获取电影详细信息,并将获取的数据传递给名为的函数setupMovieInfo(data)



// fetching movie details
fetch(`${movie_detail_http}${movie_id}?` + new URLSearchParams({
    api_key: api_key
}))
.then(res => res.json())
.then(data => {
    setupMovieInfo(data);
})


Enter fullscreen mode Exit fullscreen mode

让我们创造吧setupMovieInfo



const setupMovieInfo = (data) => {
    const movieName = document.querySelector('.movie-name');
    const genres = document.querySelector('.genres');
    const des = document.querySelector('.des');
    const title = document.querySelector('title');
    const backdrop = document.querySelector('.movie-info');

    title.innerHTML = movieName.innerHTML = data.title; 
    genres.innerHTML = `${data.release_date.split('-')[0]} | `;
    for(let i = 0; i < data.genres.length; i++){
        genres.innerHTML += data.genres[i].name + formatString(i, data.genres.length);
    }

    if(data.adult == true){
        genres.innerHTML += ' | +18';
    }

    if(data.backdrop_path == null){
        data.backdrop_path = data.poster_path;
    }

    des.innerHTML = data.overview.substring(0, 200) + '...';

    backdrop.style.backgroundImage = `url(${original_img_url}${data.backdrop_path})`;
}


Enter fullscreen mode Exit fullscreen mode
解释

这个函数非常简单,首先它会选择所有元素,例如电影名称、标题标签、描述和类型。选择所有元素后,我们使用innerHTML方法设置值。但对于类型,我们有一些条件,例如,首先我们通过一些格式化操作只添加上映年份。之后,我们循环遍历电影数据中包含的所有类型,并将它们添加到类型中,并进行一些格式化。是的,您可以看到formatString函数,让我们来创建它。



const formatString = (currentIndex, maxIndex) => {
    return (currentIndex == maxIndex - 1) ? '' : ', ';
}


Enter fullscreen mode Exit fullscreen mode

backdrop_path类型之后,我们会像之前在主页上检查的那样进行检查。并将图片设置为背景图片。

由于我们没有获取电影详情中的演员信息,因此必须单独获取。



//fetching cast info

fetch(`${movie_detail_http}${movie_id}/credits?` + new URLSearchParams({
    api_key: api_key
}))
.then(res => res.json())
.then(data => {
    const cast = document.querySelector('.starring');
    for(let i = 0; i < 5; i++){
        cast.innerHTML += data.cast[i].name + formatString(i, 5);
    }
})


Enter fullscreen mode Exit fullscreen mode

我觉得这很容易理解。如果你有疑问,可以在讨论中问我。

现在如果我们看到输出。

输出

捕获-2 (1)

现在让我们获取视频片段。



/ fetching video clips

fetch(`${movie_detail_http}${movie_id}/videos?` + new URLSearchParams({
    api_key: api_key
}))
.then(res => res.json())
.then(data => {
    let trailerContainer = document.querySelector('.trailer-container');

    let maxClips = (data.results.length > 4) ? 4 : data.results.length;

    for(let i = 0; i < maxClips; i++){
        trailerContainer.innerHTML += `
        <iframe src="https://youtube.com/embed/${data.results[i].key}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
        `;
    }
})


Enter fullscreen mode Exit fullscreen mode

这里,我们获取与电影相关的视频详情。获取结果后,我们会检查要设置的条件maxClips,因为我们最多需要 4 个片段。之后,我们会循环maxClips播放。创建一个Iframe与 HTML 文件中相同的结构。将其从 HTML 文件中复制到 HTML 文件中。但请注意它的src属性。

输出

捕获-3

现在最后一件事是提出建议。



// fetch recommendations

fetch(`${movie_detail_http}${movie_id}/recommendations?` + new URLSearchParams({
    api_key: api_key
}))
.then(res => res.json())
.then(data => {
    let container = document.querySelector('.recommendations-container');
    for(let i = 0; i < 16; i++){
        if(data.results[i].backdrop_path == null){
            i++;
        }
        container.innerHTML += `
        <div class="movie" onclick="location.href = '/${data.results[i].id}'">
            <img src="${img_url}${data.results[i].backdrop_path}" alt="">
            <p class="movie-title">${data.results[i].title}</p>
        </div>
        `;
    }
})


Enter fullscreen mode Exit fullscreen mode

项目的最后一步,我们从 TMDB 中获取类似的电影。获取数据后,我们只制作了 16 张卡片。这与我们之前在 中创建卡片的方法非常相似home.js

输出

捕获-4

我们完成了。

好了,就是这样。希望你理解了所有内容。如果你有疑问或者我遗漏了什么,请在评论区告诉我。

您可能觉得有用的文章

  1. 无限 CSS 加载器
  2. 最佳 CSS 效果
  3. 波浪按钮悬停效果
  4. Youtube API - Youtube 克隆
  5. 渐变复选框

如果你能订阅我的YouTube频道,我将不胜感激。我创作了精彩的网络内容。订阅吧

源代码

感谢您的阅读。

文章来源:https://dev.to/themodernweb/how-to-create-netflix-clone-netflix-clone-with-hmtl-css-js-989
PREV
🔥🔥 如何在 css 中设置选择输入的样式演示视频教程 - 让我们开始编码吧
NEXT
CSS 弹性框:你需要了解的关于弹性框的一切 什么是弹性框?如何使用弹性框?让我们看看一些你可以使用的弹性框属性。你可能会觉得有用的文章