前端項(xiàng)目開(kāi)發(fā)中,大家可能多少都有用到過(guò)輪播圖。一般為了省事,我們會(huì)使用現(xiàn)成的庫(kù),比如swiper。當(dāng)然,很多組件庫(kù)也帶有輪播圖組件,比如element-ui的ElCarousel組件。但是,有多少童鞋曾思考過(guò)其實(shí)現(xiàn)原理呢?又有多少童鞋嘗試過(guò)手寫(xiě)一個(gè)呢?
其實(shí),實(shí)現(xiàn)一個(gè)輪播圖相當(dāng)簡(jiǎn)單,我打算出一個(gè)大約3節(jié)的連載教程,教大家怎樣一步一步實(shí)現(xiàn)輪播圖。今天,我們先講解結(jié)構(gòu)和布局的設(shè)計(jì)。
首先,我們創(chuàng)建一個(gè)項(xiàng)目文件夾carousel-demo,在該目錄下新建images文件夾和index.html,main.js,style.css三個(gè)文件。然后,大家找3張相同尺寸的banner圖和2個(gè)相同尺寸的小圖標(biāo)放入images文件夾。我用的banner圖尺寸是1280*720,文件名分別是1.jpg,2.jpg,3.jpg;我用的圖標(biāo)尺寸是32*32,文件名分別是left.png和right.png。
最終,我們實(shí)現(xiàn)的輪播圖界面長(zhǎng)這樣,大家說(shuō)漂不漂亮?
接下來(lái),我們打開(kāi)index.html文件,先創(chuàng)建一個(gè)基本的骨架,并引入我們剛才創(chuàng)建的css和js文件,代碼如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Carousel demo</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="main.js"></script>
</body>
</html>
我們的輪播圖需要一個(gè)外層容器元素,該元素包含一個(gè)banner列表,一個(gè)指示器和一組左右導(dǎo)航按鈕。由于默認(rèn)顯示第一張圖片,所以我們給第一個(gè)指示器項(xiàng)添加了一個(gè)active類(lèi)。代碼如下:
<div class="carousel-wrapper">
<ul class="slides">
<li class="slide-item">
<img src="images/1.jpg">
</li>
<li class="slide-item">
<img src="images/2.jpg">
</li>
<li class="slide-item">
<img src="images/3.jpg">
</li>
</ul>
<ul class="indicators">
<li class="indicator-item active"></li>
<li class="indicator-item"></li>
<li class="indicator-item"></li>
</ul>
<ul class="nav">
<li class="nav-left"></li>
<li class="nav-right"></li>
</ul>
</div>
現(xiàn)在,我們打開(kāi)style.css文件,首先對(duì)默認(rèn)樣式做一些重置,將所有元素的內(nèi)外邊距設(shè)為0,盒模型設(shè)為邊框盒。為了去掉li元素前面的小圓點(diǎn),我們將li元素的list-style設(shè)為none。樣式如下:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
接下來(lái),我們從外到內(nèi),從上到下為元素定義樣式。
首先,我們定義外層容器元素的樣式。為了使布局更靈活,我們先給它指定一個(gè)最大寬度,并讓其在水平方向居中。由于它的子元素需要堆疊,我們給它設(shè)置相對(duì)定位,讓子元素相對(duì)于它來(lái)定位。由于我們的banner列表有多張圖片,可以左右滾動(dòng),每次僅一張圖片可見(jiàn),所以需要將不可見(jiàn)的圖片裁掉。樣式如下:
.carousel-wrapper {
max-width: 800px;
margin: auto;
position: relative;
overflow: hidden;
}
接下來(lái),我們定義banner列表和其子元素樣式。我們的banner列表有3張圖片,可以左右滾動(dòng),每次僅顯示一張,所以banner的寬度與容器一樣,banner列表寬度是容器的3倍。
我們將banner列表元素顯示為彈性盒,以讓所有banner在一行排列顯示。由于彈性盒子元素會(huì)均分空間,而我們的banner圖寬度相同,所以不需要設(shè)置banner的寬度,僅將banner內(nèi)的img元素寬度設(shè)為100%即可。
我們也為banner列表添加了過(guò)渡屬性,當(dāng)使用JS動(dòng)態(tài)改變變換值的時(shí)候會(huì)有動(dòng)畫(huà)效果。樣式如下:
.slides {
width: 300%;
display: flex;
transition: transform .3s;
}
.slide-item img {
display: block;
width: 100%;
}
下面,我們定義指示器樣式。我們的指示器需要在banner列表上層底部居中顯示,我們使用left和X軸平移變換結(jié)合實(shí)現(xiàn)水平居中,全部樣式如下:
.indicators {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
display: flex; // 彈性盒,讓子元素在一行顯示
padding: 5px;
border-radius: 10px;
background-color: rgba(255, 255, 255, .3);
pointer-events: none; // 阻止指示器容器成為指針事件目標(biāo)
}
.indicator-item {
pointer-events: all; // 讓指示器子元素可以成為指針事件目標(biāo)
cursor: pointer;
width: 30px;
height: 6px;
margin: 0 4px;
border-radius: 6px;
background-color: #999;
}
.indicator-item.active { // 為活動(dòng)指示器項(xiàng)設(shè)置一個(gè)不同的樣式
background-color: #ccc;
}
最后,我們定義導(dǎo)航按鈕樣式。我們的導(dǎo)航按鈕需要在banner列表上層兩邊垂直方向居中顯示,我們使用top和Y軸平移變換結(jié)合實(shí)現(xiàn)垂直居中,全部樣式如下:
.nav li {
cursor: pointer;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 40px;
height: 40px;
background-color: rgba(255, 255, 255, .3);
background-repeat: no-repeat;
background-position: center;
background-size: 24px;
}
.nav-left {
left: 0;
background-image: url(images/left.png);
}
.nav-right {
right: 0;
background-image: url(images/right.png);
}
以上就是本文的全部?jī)?nèi)容了,童鞋們都理解了嗎?還有什么不懂的歡迎評(píng)論區(qū)提問(wèn),感謝閱讀!
體代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{margin: 0;
padding: 0;}
#box {
width: 100%;
height: 502px;
overflow: hidden;/*溢出的部分:隱藏*/
}
#box .menu {
width: 607%;
position: relative;
margin-left: -40px;/*左外邊距*/
bottom: 0px;/*低邊距離*/
}
#box .menu ul li {
float: left;/*浮動(dòng):左,就是要把圖片往左浮動(dòng)*/
list-style: none;
}
</style>
</head>
<body>
<div id="box"><!--最外的大盒子-->
<div class="menu"><!--這里是寫(xiě)入我們要播放的圖片-->
<ul><!--無(wú)序列表-->
<li><img src="image/01.jpg" width="1546px;" height="500px"></li>
<li><img src="image/02.jpg" width="1546px;" height="500px"></li>
<li><img src="image/03.jpg" width="1546px;" height="500px"></li>
<li><img src="image/04.jpg" width="1546px;" height="500px"></li>
<li><img src="image/05.jpg" width="1546px;" height="500px"></li>
<li><img src="image/06.jpg" width="1546px;" height="500px"></li>
</ul>
</div>
</div>
<!--在這里導(dǎo)入javascript文件也就是js代碼,如果沒(méi)有這個(gè)就沒(méi)有動(dòng)畫(huà)-->
<script src="jquery-3.4.1.min.js" type="text/javascript"></script>
<!--寫(xiě)代碼-->
<script>
// function就是函數(shù)執(zhí)行
$(function(){
//一般獲取元素用var,從第一張圖片開(kāi)始
var _index=0,
// 窗口寬度,就是把所有圖片放在水平線(xiàn)上的總寬度
window_width=1546,
//時(shí)間循環(huán)
timer=null,
//圖片內(nèi)容一共六張
images_count=6;
//獲取下一個(gè)
function nextPlay(){
if(_index>images_count-1){//_index指的是每一張圖片
_index=0;//從第一張開(kāi)始
//stop() 停留,animate自定義動(dòng)畫(huà)往左運(yùn)動(dòng),
$("#box .menu").stop().animate({left:-window_width*_index},500);
}else{
$("#box .menu").stop().animate({left:-window_width*_index},500);
}
//每一個(gè)圖片加一就是自動(dòng)按順序出來(lái)
_index++;
}
timer=setInterval(nextPlay,2000);
})
</script>
</body>
</html>
javascript文件也就是js文件:鏈接:https://pan.baidu.com/s/1_RUihF6SdA4-NJcqHGqm1g
提取碼:mnfg
技術(shù)交流群里面,有人冒出來(lái)問(wèn),誰(shuí)有輪播插件,因?yàn)槲乙矝](méi)用過(guò),但是我覺(jué)得輪播這個(gè)功能其實(shí)蠻簡(jiǎn)單的,可以自己創(chuàng)造,我覺(jué)得編程的樂(lè)趣就在于創(chuàng)造,創(chuàng)造出屬于你的東西,編程才有了靈魂。
下面不多說(shuō),由于代碼有幾部分,所以圖片方式進(jìn)行代碼演示:
首先準(zhǔn)備一下材料:我使用的是jquery寫(xiě)的,所以需要準(zhǔn)備這個(gè)插件就可以了:
主要HTML代碼
解釋?zhuān)赫麄€(gè)輪播會(huì)分為3部分:一個(gè)大的div,包含了圖片、輪播節(jié)點(diǎn)、動(dòng)畫(huà)插入。其中輪播節(jié)點(diǎn)與動(dòng)畫(huà)展示使用絕對(duì)位置定位,使得它從流中脫離出來(lái),具體樣式如下圖:
主要的樣式設(shè)計(jì)
解釋?zhuān)狠啿ス?jié)點(diǎn)就是圖片地址一樣,輪到哪一張就亮哪一張。節(jié)點(diǎn)使用絕對(duì)位置,并設(shè)置位于第三層。
接下來(lái)就是使得它開(kāi)始動(dòng)起來(lái),動(dòng)起來(lái)需要使用什么方法呢?當(dāng)然了有兩種方法,一種是CSS3,另一種是使用計(jì)時(shí)器配合動(dòng)畫(huà)方法animate。CSS3這種屬于純樣式設(shè)計(jì),對(duì)于固定的來(lái)說(shuō),還是可以的,至于動(dòng)態(tài)的,后期不斷增加更改的,暫時(shí)沒(méi)去了解過(guò),所以下面使用定時(shí)器這種方法:
代碼如下:
主要js代碼
上面的代碼,主要邏輯都有注釋?zhuān)琲mglabel(i)用來(lái)實(shí)時(shí)跟蹤圖片,跟著圖片走;divanimate(i)用來(lái)每一張圖片插入動(dòng)畫(huà),里面的html屬于變量相當(dāng)于組件復(fù)用,可以往里面?zhèn)魅肽阋f(shuō)的話(huà),和其他內(nèi)容。
那么整個(gè)輪播就出來(lái),效果如下
<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
創(chuàng)造是編程的樂(lè)趣,所以歡迎小伙伴們留言,一起討論提提升。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。