如何创建 YouTube 克隆版。使用 HTML、CSS 和 JS 制作 YouTube 克隆版。视频教程代码 最后一件事 - 搜索框 你可能觉得有用的文章

2025-05-28

如何创建 YouTube 克隆版。使用 HTML、CSS、JS 创建 YouTube 克隆版。

视频教程

代码

最后一件事 - 搜索框

您可能觉得有用的文章

您好,欢迎!今天我们将学习如何仅使用 HTML、CSS 和 JS 轻松创建一个 YouTube 克隆版本,无需其他库。我们还将使用 YouTube API 从 YouTube 获取真实数据。

我们的克隆版有很多功能。比如,它看起来像 YouTube。所有视频数据都直接来自 YouTube。我们还提供了可用的搜索栏,可以将用户重定向到 YouTube 官方搜索页面。而且,每当用户点击视频卡时,他/她都会被重定向到 YouTube 的官方视频页面。

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

视频教程

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

代码

下载项目图片下载源代码

首先,这个项目有 3 个文件index.htmlstyle.cssapp.js。我们使用非常基础的 CSS,所以我不会详细解释每个 CSS 属性。但是,如果您有任何疑问,请随时在评论区提问。我们将理解每一行 JavaScript。

首先让我们创建导航栏。我们的导航栏 HTML 结构。



<nav class="navbar">
    <div class="toggle-btn">
        <span></span>
        <span></span>
        <span></span>
    </div>
    <img src="img/logo.PNG" class="logo" alt="">
    <div class="search-box">
        <input type="text" class="search-bar" placeholder="search">
        <button class="search-btn"><img src="img/search.PNG" alt=""></button>
    </div>
    <div class="user-options">
        <img src="img/video.PNG" class="icon" alt="">
        <img src="img/grid.PNG" class="icon" alt="">
        <img src="img/bell.PNG" class="icon" alt="">
        <div class="user-dp">
            <img src="img/profile-pic.png" alt="">
        </div>
    </div>
</nav>


Enter fullscreen mode Exit fullscreen mode

输出 现在给它一些 CSS。
捕获



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

*:focus{
    outline: none;
}

body{
    position: relative;
    background: #f0f0f0;
    font-family: 'roboto', sans-serif;
}

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

.toggle-btn{
    width: 20px;
    height: 10px;
    position: relative;
    cursor: pointer;
}

.toggle-btn span{
    position: absolute;
    width: 100%;
    height: 2px;
    top: 50%;
    transform: translateY(-50%);
    background: #979797;
}

.toggle-btn span:nth-child(1){
    top: 0;
}

.toggle-btn span:nth-child(3){
    top: 100%;
}

.logo{
    height: 30px;
    margin: -10px 30px 0;
}

.search-box{
    position: relative;
    max-width: 500px;
    width: 50%;
    height: 35px;
    display: flex;
}

.search-bar{
    width: 85%;
    height: 100%;
    border: 2px solid #dbdbdb;
    padding: 0 20px;
    font-size: 16px;
    text-transform: capitalize;
}

.search-btn{
    width: 15%;
    height: 100%;
    background: #f0f0f0;
    border: 2px solid #dbdbdb;
    padding: 5px 0;
    border-left: none;
}

.search-btn img{
    height: 100%;
}

.user-options{
    height: 35px;
    display: flex;
    margin-left: auto;
    align-items: center;
}

.user-options .icon{
    height: 80%;
    margin-right: 20px;
    cursor: pointer;
}

.user-dp{
    cursor: pointer;
    height: 30px;
    width: 30px;
    border-radius: 50%;
    overflow: hidden;
}

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


Enter fullscreen mode Exit fullscreen mode

输出
捕获-2

现在创建侧边导航栏。



<div class="side-bar">
    <a href="#" class="links active"><img src="img/home.PNG" alt="">home</a>
    <a href="#" class="links"><img src="img/explore.PNG" alt="">explore</a>
    <a href="#" class="links"><img src="img/subscription.PNG" alt="">subscription</a>
    <hr class="seperator">
    <a href="#" class="links"><img src="img/library.PNG" alt="">library</a>
    <a href="#" class="links"><img src="img/history.PNG" alt="">history</a>
    <a href="#" class="links"><img src="img/your-video.PNG" alt="">your video</a>
    <a href="#" class="links"><img src="img/watch-later.PNG" alt="">watch leater</a>
    <a href="#" class="links"><img src="img/liked video.PNG" alt="">like video</a>
    <a href="#" class="links"><img src="img/show more.PNG" alt="">show more</a>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS



.side-bar{
    position: fixed;
    top: 60px;
    left: 0;
    min-width: 250px;
    width: 250px;
    height: calc(100vh - 60px);
    background: #fff;
    padding-right: 10px;
}

.links{
    display: block;
    width: 100%;
    padding: 10px 20px;
    display: flex;
    align-items: center;
    text-transform: capitalize;
    color: #242424;
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
}

.links img{
    height: 25px;
    margin-right: 20px;
}

.links:hover,
.links.active{
    background: rgba(0, 0, 0, 0.1);
}

.seperator{
    border: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    margin: 20px 0;
}


Enter fullscreen mode Exit fullscreen mode

输出
捕获-3

现在,过滤器选项



<div class="filters">
    <button class="filter-options active">all</button>
    <button class="filter-options">CSS</button>
    <button class="filter-options">web development</button>
    <button class="filter-options">python</button>
    <button class="filter-options">entertainment</button>
    <button class="filter-options">marvel</button>
    <button class="filter-options">javascript</button>
    <button class="filter-options">artificial intelligence</button>
    <button class="filter-options">machine learning</button>
    <button class="filter-options">trending</button>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS



.filters{
    position: fixed;
    left: 250px;
    top: 60px;
    width: calc(100% - 250px);
    height: 60px;
    background: #fff;
    border-top: 1px solid #dbdbdb;
    border-bottom: 1px solid #dbdbdb;
    padding: 0 20px;
    display: flex;
    align-items: center;
    overflow-x: auto;
    overflow-y: hidden;
}

.filters::-webkit-scrollbar{
    display: none;
}

.filter-options{
    flex: 0 0 auto;
    padding: 10px 20px;
    border-radius: 50px;
    background: #f0f0f0;
    border: 1px solid #dbdbdb;
    text-transform: capitalize;
    margin-right: 10px;
    color: #242424;
    font-size: 15px;
    cursor: pointer;
}

.filter-options.active{
    color: #fff;
    background: #242424;
}


Enter fullscreen mode Exit fullscreen mode

输出
捕获-4

现在到了最后也是最重要的事情:制作视频卡片。我们将使用 JS 动态创建卡片。因此,出于样式方面的考虑,我们将用 HTML 创建一个卡片。并确保为所有视频卡片创建一个容器。



<div class="video-container">
    <div class="video">
        <img src="img/profile-pic.png" class="thumbnail" alt="">
        <div class="content">
            <img src="img/profile-pic.png" class="channel-icon" alt="">
            <div class="info">
                <h4 class="title">youtube clone 2021 | create working youtube clone</h4>
                <p class="channel-name">modern web</p>
            </div>
        </div>
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode

CSS



.video-container{
    width: calc(100% - 250px);
    margin-top: 120px;
    margin-left: 250px;
    padding: 20px;
    display: grid;
    grid-template-columns: repeat(4, 25%);
    grid-gap: 20px 5px;
    overflow-x: hidden;
}

.video{
    min-height: 250px;
    height: auto;
}

.thumbnail{
    width: 100%;
    height: 150px;
    object-fit: cover;
}

.content{
    width: 100%;
    height: 100px;
    padding: 10px;
    display: flex;
    justify-content: space-between;
}

.channel-icon{
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    margin-right: 10px;
}

.title{
    width: 100%;
    height: 40px;
    overflow: hidden;
}

.channel-name{
    font-size: 14px;
    margin: 2px 0;
    color: #979797;
}


Enter fullscreen mode Exit fullscreen mode

输出
捕获-5

现在我们已经完成了样式设置。我们不需要 HTML 卡片结构了。所以,请对其进行注释。



<div class="video-container">
    <!-- <div class="video">
        <img src="img/profile-pic.png" class="thumbnail" alt="">
        <div class="content">
            <img src="img/profile-pic.png" class="channel-icon" alt="">
            <div class="info">
                <h4 class="title">youtube clone 2021 | create working youtube clone</h4>
                <p class="channel-name">modern web</p>
            </div>
        </div>
    </div> -->
</div>


Enter fullscreen mode Exit fullscreen mode

现在去创建 YouTube API 密钥。观看此视频了解如何创建 YouTube API 密钥。API密钥

获得 API 密钥后,将其存储在app.js文件中的变量中。



let api_key = "your api key";


Enter fullscreen mode Exit fullscreen mode

现在开始获取视频。我们需要 YouTube API 路由。你可以在 YouTube 文档中找到它。
捕获-6

并将此链接添加到JS文件中。



let api_key = "your api key";
let video_http = "https://www.googleapis.com/youtube/v3/videos?";


Enter fullscreen mode Exit fullscreen mode

注意:在链接的最后添加“?”,因为我们需要给这个链接添加一些参数。

现在使用 fetch 方法fetch()从 youtube 获取数据。



fetch(video_http + new URLSearchParams({
    key: api_key,
    part: 'snippet',
    chart: 'mostPopular',
    maxResults: 50,
    regionCode: 'IN'
}))
.then(res => res.json())
.then(data => {
    data.items.forEach(item => {
        getChannelIcon(item);
    })
})
.catch(err => console.log(err));


Enter fullscreen mode Exit fullscreen mode
解释

您可以看到,我们正在从 YouTube 文档中获取的“video_http”获取数据。为了向 URL 添加参数,我们使用了new URLSearchParama(object)。传递代码中提到的参数。它们的含义不言自明。parampart定义了我们需要的数据类型,在本例中,我们需要所有与视频相关的数据。因此,传递snippet

获取数据后,我们通过 将其转换为 JSON res.json()。您可以查看 YouTube 数据结构。 我们需要的所有数据都在 item 的数组中。因此,从循环获取 JSON 数据后,通过using方法将该 item 传递给名为 的函数
捕获-7
res.json()data.itemsforEach()getChannelIcon(item)

这个函数的作用是什么?嗯,如果你查看 YouTube 视频的数据,它包含了所有内容,但没有频道图标。而我们也需要频道图标。所以我们必须单独获取图标。使用“channel_http”

去 youtube 的文档中查找频道数据的 http。
捕获-8

并将此 HTTP 存储在我们的app.js文件中。在我们的video_http变量下面。



let video_http = "https://www.googleapis.com/youtube/v3/videos?";
let channel_http = "https://www.googleapis.com/youtube/v3/channels?";


Enter fullscreen mode Exit fullscreen mode

然后在链接末尾添加“?”。
现在,实现该getChannelIcon功能。



const getChannelIcon = (video_data) => {
    fetch(channel_http + new URLSearchParams({
        key: api_key,
        part: 'snippet',
        id: video_data.snippet.channelId
    }))
    .then(res => res.json())
    .then(data => {
        video_data.channelThumbnail = data.items[0].snippet.thumbnails.default.url;
        makeVideoCard(video_data);
    })
}


Enter fullscreen mode Exit fullscreen mode
解释

在这个函数中,我们获取单个视频的数据,因为我们调用了循环,记得吗?获取单个视频的数据后,我们向 YouTube API 请求频道信息。再次使用URLSearchParam添加参数。video_data.snippet.channelId传入id参数。获取响应后,通过调用 将其转换为 JSON res.json(),并将数据转换为 JSON。设置video_data.channelThumbnaildata.items[0].snippet.thumbnails.default.url

通过这种方式,我们成功地将频道图标 URL 添加到了我们的实际视频数据中。

此后,我们调用另一个函数makeVideoCard(data)。此函数用于创建卡片。

现在,创建视频卡。但在创建此功能之前,请从 HTML 中选择我们的视频容器元素。



const videoCardContainer = document.querySelector('.video-container');


Enter fullscreen mode Exit fullscreen mode


const makeVideoCard = (data) => {
    videoCardContainer.innerHTML += `
    <div class="video" onclick="location.href = 'https://youtube.com/watch?v=${data.id}'">
        <img src="${data.snippet.thumbnails.high.url}" class="thumbnail" alt="">
        <div class="content">
            <img src="${data.channelThumbnail}" class="channel-icon" alt="">
            <div class="info">
                <h4 class="title">${data.snippet.title}</h4>
                <p class="channel-name">${data.snippet.channelTitle}</p>
            </div>
        </div>
    </div>
    `;
}


Enter fullscreen mode Exit fullscreen mode
解释

在这个函数中,由于我们需要将卡片附加到视频容器元素中,因此请使用innerHTML方法在元素内添加 HTML 代码videoContainer。记住使用+=而不是 ,=因为我们要添加 HTML 代码而不是重写 HTML。

好了,我们添加的内容是,我们已经有了 HTML 卡片结构。复制代码并粘贴到这里。但template string在这里使用。这样,添加带有文本的变量就很容易了。

粘贴HTML结构后,删除实际的图像来源和标题,频道名称改为使用${variable}它来添加变量。

video元素内部的最后一项用于onclick="location.href = 'https://youtube.com/watch?v=${data.id}'"添加点击事件。

我们的视频卡已经完成了。

输出
捕获-9

最后一件事 - 搜索框

要使搜索框发挥作用,首先选择搜索框和搜索按钮。



const searchInput = document.querySelector('.search-bar');
const searchBtn = document.querySelector('.search-btn');


Enter fullscreen mode Exit fullscreen mode

并创建一个变量来存储搜索路线。



let searchLink = "https://www.youtube.com/results?search_query=";


Enter fullscreen mode Exit fullscreen mode

好吧,我从哪里得到这个链接呢?你可以在下图中看到。你可以看到,这是一个 YouTube 用来搜索视频的真实链接。我们可以用这个 URL,只需要修改一下param 的值。
捕获-10
search_query

现在,我们拿到了链接。给按钮添加点击事件,并验证搜索框。像这样。



searchBtn.addEventListener('click', () => {
    if(searchInput.value.length){
        location.href = searchLink + searchInput.value;
    }
})


Enter fullscreen mode Exit fullscreen mode

并且在该条件内使用location.href重定向用户。

我们完成了。

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

您可能觉得有用的文章

  1. CSS 位置
  2. CSS媒体查询
  3. CSS 弹性框
  4. 无限 CSS 加载器

如果你喜欢,可以订阅我的YouTube频道。我创作了很棒的网页内容。订阅

感谢您的阅读。

文章来源:https://dev.to/themodernweb/create-working-youtube-clone-with-search-box-youtube-api-2a6e
PREV
CSS 位置:优秀开发人员所需的一切让我们更详细地了解它们。
NEXT
🔥🤯 使用 HTML、CSS 和 JS 的精彩作品集网站。您可能会发现有用的视频教程代码文章,分享现场演示有什么问题,aleman 先生?