如何使用纯 HTML、CSS、JS 视频教程代码文章创建 Disney Plus 克隆,您可能会发现有用

2025-05-28

如何使用纯 HTML、CSS、JS 创建 Disney+ 克隆版

视频教程

代码

您可能觉得有用的文章

大家好,今天我们将学习如何仅使用 HTML、CSS 和 JS 轻松创建迪士尼 Plus 的 UI 克隆版,无需其他库。我们还将学习如何实现无限滑动的效果。我花了 2-3 个小时来编写代码。

我们的克隆版与迪士尼+原版网站非常相似。它只有一页(首页)。它拥有与迪士尼+相同的导航栏和搜索框,点击效果也很酷炫,此外还有一个滑块或轮播,可以无限滚动或无限循环。这对我来说一开始很难做到。之后,我们还添加了电影卡片,并拥有超棒的卡片悬停效果。此外,我们还提供更多功能。

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

视频教程

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

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

代码

在我们开始编写代码之前。虽然它不是一个 Node 应用,但我们至少应该了解一下它的文件夹结构。

第 7 帧

下载模板

您可以看到我们有一个名为的文件data.js。此文件包含我们的电影滑块数据。您可以在下面看到。



let movies = [
    {
        name: 'falcon and the winter soldier',
        des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
        image: 'images/slider 2.PNG'
    },
    {
        name: 'loki',
        des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
        image: 'images/slider 1.PNG'
    },
    {
        name: 'wanda vision',
        des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
        image: 'images/slider 3.PNG'
    },
/// and so on
]


Enter fullscreen mode Exit fullscreen mode

如果您看到起始数据,您会注意到我们的数据slide-1位于列表的第二个数字上。这是为什么呢?那是因为。我们的滑块一次会有三张幻灯片,我们希望活动幻灯片位于中心。这意味着当我们第一次从幻灯片数据开始时,我们的活动幻灯片或第一张幻灯片将位于中间。我希望这说得通。如果不通,请观看视频教程以更好地理解。

现在让我们编写网页代码。

网页。

从 开始index.html。编写基本的 HTML 结构并链接 CSS 和 JS 文件。确保data.js在 之前添加 file app.js。这样我们就可以访问 file 中的数据app.js

现在首先创建导航栏。



<nav class="navbar">
    <img src="images/logo.png" class="brand-logo" alt="">
    <ul class="nav-links">
        <li class="nav-items"><a href="#">TV</a></li>
        <li class="nav-items"><a href="#">movies</a></li>
        <li class="nav-items"><a href="#">sports</a></li>
        <li class="nav-items"><a href="#">premium</a></li>
    </ul>

    <div class="right-container">
        <input type="text" class="search-box" placeholder="search">
        <button class="sub-btn">subscribe</button>
        <a href="#" class="login-link">login</a>
    </div>
</nav>


Enter fullscreen mode Exit fullscreen mode


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

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

.navbar{
    width: 100%;
    height: 80px;
    position: fixed;
    top: 0;
    left: 0;
    padding: 0 4%;
    background: #0c111b;
    z-index: 9;
    display: flex;
    align-items: center;
}

.brand-logo{
    height: 70px;
}

.nav-links{
    margin-top: 10px;
    display: flex;
    list-style:none;
}

.nav-items a{
    text-decoration: none;
    margin-left: 20px;
    text-transform: capitalize;
    color: #fff;
    opacity: 0.9;
}

.right-container{
    display: block;
    margin-left: auto;
}

.search-box{
    border: none;
    border-bottom: 1px solid #aaa;
    background: transparent;
    outline: none;
    height: 30px;
    color:#fff;
    width: 250px;
    text-transform: capitalize;
    font-size: 16px;
    font-weight: 500;
    transition: .5s;
}

.search-box:focus{
    width: 400px;
    border-color: #1f80e0;
}

.sub-btn{
    background: #1f80e0;
    height: 30px;
    padding: 0 20px;
    color: #fff;
    border-radius: 5px;
    border: none;
    outline: none;
    text-transform: uppercase;
    font-weight: 700;
    font-size: 12px;
    margin: 0 10px;
}

.login-link{
    color: #fff;
    opacity: 0.9;
    text-transform: uppercase;
    font-size: 15px;
    font-weight: 700;
    text-decoration: none;
}


Enter fullscreen mode Exit fullscreen mode
输出

捕获

现在我们来制作滑块。我们将使用 JS 创建这些滑块,但出于样式方面的考虑,暂时先用 HTML 创建一个。



div class="carousel-container">
    <div class="carousel">
        <div class="slider">
            <div class="slide-content">
                <h1 class="movie-title">loki</h1>
                <p class="movie-des">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Suscipit saepe eius ratione nostrum mollitia explicabo quae nam pariatur. Sint, odit?</p>
            </div>
            <img src="images/slider 1.PNG" alt="">
        </div>
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode


.carousel-container{
    position: relative;
    width: 100%;
    height: 450px;
    padding: 20px 0;
    overflow-x: hidden;
    margin-top: 80px;
}

.carousel{
    display: flex;
    width: 92%;
    height: 100%;
    position: relative;
    margin: auto;
}

.slider{
    flex: 0 0 auto;
    margin-right: 30px;
    position: relative;
    background: rgba(0, 0, 0,0.5);
    border-radius: 5px;
    width: 100%;
    height: 100%;
    left: 0;
    transition: 1s;
    overflow: hidden;
}

.slider img{
    width: 70%;
    min-height: 100%;
    object-fit: cover;
    display: block;
    margin-left: auto;
}

.slide-content{
    position: absolute;
    width: 50%;
    height: 100%;
    z-index: 2;
    background: linear-gradient(to right, #030b17 80%, #0c111b00);
    color: #fff;
}

.movie-title{
    padding-left: 50px;
    text-transform: capitalize;
    margin-top: 80px;
}

.movie-des{
    width: 80%;
    line-height: 30px;
    padding-left: 50px;
    margin-top: 30px;
    opacity: 0.8;
}


Enter fullscreen mode Exit fullscreen mode
输出

捕获2
现在您可以评论幻灯片了。我们已经完成了样式设置。现在
,让这个滑块可以正常工作。观看此视频,了解滑块的工作原理。

在里面app.js。选择我们的轮播元素并创建一个空数组来存储所有幻灯片。



const carousel = document.querySelector('.carousel');
let sliders = [];

let slideIndex = 0; // to track current slide index.


Enter fullscreen mode Exit fullscreen mode

现在创建一个createSlide用于创建幻灯片的函数。



const createSlide = () => {
    if(slideIndex >= movies.length){
        slideIndex = 0;
    }

    // creating DOM element
    let slide = document.createElement('div');
    let imgElement = document.createElement('img');
    let content = document.createElement('div');
    let h1 = document.createElement('h1');
    let p = document.createElement('p');
}


Enter fullscreen mode Exit fullscreen mode

在这个函数中,我们首先使用slideIndex一些 if/else 条件来增加或设置下一个值。之后,我们创建幻灯片所需的 DOM 元素。所有这些元素都与我们之前创建的完全相同index.html

创建所有这些元素后,将这些元素附加/附加到彼此以形成 HTML 结构。



{
    // attaching all elements
    imgElement.appendChild(document.createTextNode(''));
    h1.appendChild(document.createTextNode(movies[slideIndex].name));
    p.appendChild(document.createTextNode(movies[slideIndex].des));
    content.appendChild(h1);
    content.appendChild(p);
    slide.appendChild(content);
    slide.appendChild(imgElement);
    carousel.appendChild(slide);
}


Enter fullscreen mode Exit fullscreen mode

此代码位于createSlide函数内部。

将元素附加到一起后,现在设置它们的类名并设置图像的来源。



{
    // setting up image
    imgElement.src = movies[slideIndex].image;
    slideIndex++;

    // setting elements classname
    slide.className = 'slider';
    content.className = 'slide-content';
    h1.className = 'movie-title';
    p.className = 'movie-des';

    sliders.push(slide);
}


Enter fullscreen mode Exit fullscreen mode

最后记得推动slide内部sliders数组。

滑块创建完毕。但是滑块无法正常工作,因为我们必须将第一张滑块向左移动。为此,请在函数末尾添加以下代码。



{
    if(sliders.length){
        sliders[0].style.marginLeft = `calc(-${100 * (sliders.length - 2)}% - ${30 * (sliders.length - 2)}px)`;
    }
}


Enter fullscreen mode Exit fullscreen mode

现在,如果您创建幻灯片,您将看到我们的滑块是否正常工作。



for(let i = 0; i < 3; i++){
    createSlide();
}

setInterval(() => {
    createSlide();
}, 3000);


Enter fullscreen mode Exit fullscreen mode

滑块部分已经制作完毕。现在开始创建视频卡。



<div class="video-card-container">
    <div class="video-card">
        <img src="images/disney.PNG" class="video-card-image" alt="">
        <video src="videos/disney.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/pixar.PNG" class="video-card-image" alt="">
        <video src="videos/pixar.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/marvel.PNG" class="video-card-image" alt="">
        <video src="videos/marvel.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/star-wars.PNG" class="video-card-image" alt="">
        <video src="videos/star-war.mp4" mute loop class="card-video"></video>
    </div>
    <div class="video-card">
        <img src="images/geographic.PNG" class="video-card-image" alt="">
        <video src="videos/geographic.mp4" mute loop class="card-video"></video>
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode


.video-card-container{
    position: relative;
    width: 92%;
    margin: auto;
    height: 10vw;
    display: flex;
    margin-bottom: 20px;
    justify-content: space-between;
}

.video-card{
    position: relative;
    min-width: calc(100%/5 - 10px);
    width: calc(100%/5 - 10px);
    height: 100%;
    border-radius: 5px;
    overflow: hidden;
    background: #030b17;
}

.video-card-image,
.card-video{
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.card-video{
    position: absolute;
}

.video-card:hover .video-card-image{
    display: none;
}


Enter fullscreen mode Exit fullscreen mode
输出

捕获3
并使视频在悬停卡片上播放。代码如下。



/// video cards

const videoCards = [...document.querySelectorAll('.video-card')];

videoCards.forEach(item => {
    item.addEventListener('mouseover', () => {
        let video = item.children[1];
        video.play();
    })
    item.addEventListener('mouseleave', () => {
        let video = item.children[1];
        video.pause();
    })
})


Enter fullscreen mode Exit fullscreen mode

此效果仅在用户首先点击您的网站时才会生效。如果用户未先点击您的页面,则由于 Google Chrome 政策,视频将无法播放。

最后,我们来制作卡片。



    <h1 class="title">recommended for you</h1>
    <div class="movies-list">
        <button class="pre-btn"><img src="images/pre.png" alt=""></button>
        <button class="nxt-btn"><img src="images/nxt.png" alt=""></button>
        <div class="card-container">
            <div class="card">
                <img src="images/poster 1.png" class="card-img" alt="">
                <div class="card-body">
                    <h2 class="name">movie name</h2>
                    <h6 class="des">Lorem ipsum dolor sit amet consectetur.</h6>
                    <button class="watchlist-btn">add to watchlist</button>
                </div>
            </div> 
            ...20+ more cards
        </div>
   </div>
.. repeat this whole block 3-4 times with different card content


Enter fullscreen mode Exit fullscreen mode


.title{
    color: #fff;
    opacity: 0.9;
    padding-left: 4%;
    text-transform: capitalize;
    font-size: 22px;
    font-weight: 500;
}

.movies-list{
    width: 100%;
    height: 220px;
    position: relative;
    margin: 10px 0 20px;
}

.card-container{
    position: relative;
    width: 92%;
    padding-left: 10px;
    height: 220px;
    display: flex;
    margin: 0 auto;
    align-items: center;
    overflow-x: auto;
    overflow-y: visible;
    scroll-behavior: smooth;
}

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

.card{
    position: relative;
    min-width: 150px;
    width: 150px;
    height: 200px;
    border-radius: 5px;
    overflow: hidden;
    margin-right: 10px;
    transition: .5s;
}

.card-img{
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.card:hover{
    transform: scale(1.1);
}

.card:hover .card-body{
    opacity: 1;
}

.card-body{
    opacity: 0;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    background: linear-gradient(to bottom, rgba(4, 8, 15, 0), #192133 90%);
    padding: 10px;
    transition: 0.5s;
}

.name{
    color: #fff;
    font-size: 15px;
    font-weight: 500;
    text-transform: capitalize;
    margin-top: 60%;
}

.des{
    color: #fff;
    opacity: 0.8;
    margin: 5px 0;
    font-weight: 500;
    font-size: 12px;
}

.watchlist-btn{
    position: relative;
    width: 100%;
    text-transform: capitalize;
    background: none;
    border: none;
    font-weight: 500;
    text-align: right;
    color: rgba(255, 255, 255, 0.5);
    margin: 5px 0;
    cursor: pointer;
    padding: 10px 5px;
    border-radius: 5px;
}

.watchlist-btn::before{
    content: '';
    position: absolute;
    top: 0;
    left: -5px;
    height: 35px;
    width: 35px;
    background-image: url(images/add.png);
    background-size: cover;
    transform: scale(0.4);
}

.watchlist-btn:hover{
    color: #fff;
    background: rgba(255, 255, 255, 0.1);
}

.pre-btn,
.nxt-btn{
    position: absolute;
    top: 0;
    width: 5%;
    height: 100%;
    z-index: 2;
    border: none;
    cursor: pointer;
    outline: none;
}

.pre-btn{
    left: 0;
    background: linear-gradient(to right, #0c111b 0%, #0c111b00);
}

.nxt-btn{
    right: 0;
    background: linear-gradient(to left, #0c111b 0%, #0c111b00);
}

.pre-btn img,
.nxt-btn img{
    width: 15px;
    height: 20px;
    opacity: 0;
}

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


Enter fullscreen mode Exit fullscreen mode
输出

Capture4

我们快完成了。最后一步是让这个卡片滑块正常工作。为此,请app.js再次打开。



// card sliders

let cardContainers = [...document.querySelectorAll('.card-container')];
let preBtns = [...document.querySelectorAll('.pre-btn')];
let nxtBtns = [...document.querySelectorAll('.nxt-btn')];

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

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

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


Enter fullscreen mode Exit fullscreen mode

我们已经完成了。

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

您可能觉得有用的文章

  1. 无限 CSS 加载器
  2. 最佳 CSS 效果
  3. 波浪按钮悬停效果
  4. Youtube API - Youtube 克隆
  5. TMDB - Netflix 克隆

如果您能订阅我的YouTube频道,我将不胜感激。我创作了非常棒的网络内容。

感谢您的阅读。

文章来源:https://dev.to/themodernweb/how-to-create-disney-plus-clone-for-beginner-in-2021-html-css-js-m3p
PREV
如何使用纯 HTML 和 CSS 创建完全响应式产品卡片。视频教程和代码教程可能会对您有所帮助
NEXT
FullStack - 如何在 2021 年使用纯 HTML、CSS 和 JS 创建一个可运行的博客网站。视频教程代码文章,您可能会觉得有用