之前的文章,由於在博文的底部放有微信公眾號的緣故,被管理員判定為:
您好,您的這篇博文內容本身沒什么問題,但是,在博文底部存在推廣信息內容。。。。
你們也沒告知到底是哪條觸犯了博客園的規矩,我就把底部信息全部刪除,這樣總行了吧。
視頻地址:http://v.qq.com/page/e/5/t/e0149n5he5t.html
大家好,歡迎來到【三石jQuery視頻教程】,我是您的老朋友 - 三生石上。
今天,我們要通過基本的HTML、CSS和jQuery來實現一個超級簡單的圖片循環展示效果,先來看下最終的產品:

Step1:網站目錄
網站目錄非常簡單,包含三部分:lesson1.html文件、lib目錄和images目錄。
其中 lesson1.html 包含了一個頁面最基本的組成部分,正確的設置 DOCTYPE 有助於頁面在現代瀏覽器中正確渲染。
<!DOCTYPE html>
<html>
<head>
<title>圖片循環展示 - 三石jQuery視頻教程</title>
</head>
<body>
</body>
</html>
lib目錄僅包含了最新的 jQuery 庫;images目錄包含了 6 張大圖和相應的 6 張小圖(小圖放在 images/small 子目錄中)。
Step2:頁面結構
為頁面添加基本的 html 標簽,包含 id=main 的內容塊,以及 class=showit 的超鏈接。
- 使用超鏈接的 class 屬性來標記哪些圖片用於大圖展示
- 使用超鏈接的 href 屬性記錄需要展示的大圖地址
- 超鏈接的內容則是頁面上顯示的縮略圖
<!DOCTYPE html>
<html>
<head>
<title>圖片循環展示 - 三石jQuery視頻教程</title>
</head>
<body>
<div id="main">
<h2>
圖片循環展示 - 三石jQuery視頻教程
</h2>
<a class="showit" href="images/1.jpg">
<img src="images/small/1.jpg">
</a>
<a class="showit" href="images/2.jpg">
<img src="images/small/2.jpg">
</a>
<a class="showit" href="images/3.jpg">
<img src="images/small/3.jpg">
</a>
<a class="showit" href="images/4.jpg">
<img src="images/small/4.jpg">
</a>
<a class="showit" href="images/5.jpg">
<img src="images/small/5.jpg">
</a>
<a class="showit" href="images/6.jpg">
<img src="images/small/6.jpg">
</a>
</div>
</body>
</html>
Step3:CSS樣式
下面我們來創建基本的 CSS 樣式,讓這個默認顯示看起來更加專業和美觀,我們所做的努力包含:
- 頁面背景設為非常淺的灰色(#efefef)
- 主體內容加上了邊框和白色背景
- 主體內容居中(margin-left 和 margin-right 設為 auto)
- 去掉了超鏈接的下划線
<style>
body{
background-color: #efefef;
}
#main {
border: solid 1px #ccc;
background-color: #fff;
max-width: 500px;
padding: 20px;
margin: 20px auto;
}
.showit {
text-decoration: none;
}
</style>
此時的頁面顯示效果:

Step4:顯示大圖
下面是 jQuery 出場的時候了,首頁在頁面底部引入 jQuery 庫。
注:把頁面上所有 JavaScript 腳本放在頁面底部是推薦的做法,這樣可以讓頁面的基本HTML結構更快的顯示出來。
基本的邏輯:
- 用戶點擊了 class=showit 的超鏈接
- 判斷 id=showbox 的大圖節點是否存在
- 如果不存在,則創建大圖節點並添加到 document.body 中
- 找到大圖節點內部的 img 標簽,並將其 src 屬性設置為所點擊超鏈接的 href 屬性
- 阻止超鏈接的默認行為 event.preventDefault()
- 判斷 id=showbox 的大圖節點是否存在
來看下相應的實現代碼:
<script>
$(function() {
$('.showit').click(function(event) {
var largeImageUrl = $(this).attr('href');
var boxEl = $('#showbox');
if(!boxEl.length) {
boxEl = $('<div>', {
id: 'showbox',
html: '<img/>'
}).appendTo(document.body);
}
boxEl.find('img').attr('src', largeImageUrl);
boxEl.show();
event.preventDefault();
});
</script>
此時,點擊頁面上的縮略圖,顯示效果如下:
Step5:大圖的CSS樣式
在沒有為大圖創建樣式時,大圖是緊挨着頁面主體結構顯示的,下面為其創建樣式:
- #showbox 絕對定位,寬度和高度設為 100%,使其填充整個頁面
- 設置 #showbox 中的內容居中顯示
- 為大圖設置隱藏和圓角,使其更美觀
#showbox {
position: absolute;
top: 0;
left: 0;
background-color: #000;
width: 100%;
height: 100%;
text-align: center;
}
#showbox img {
max-width: 500px;
margin-top: 100px;
box-shadow: 0 0 20px #fff;
border-radius: 10px;
}
此時的頁面效果:
Step6:點擊隱藏大圖
頁面第一次加載完畢后,#showbox 節點還不存在,只有用戶第一次點擊頁面上的縮略圖時才會創建 #showbox。
所以下面的代碼是不能正常運行的:
$('#showbox').click(function(event) {
$(this).hide();
});
我們需要使用 jQuery 提供的 on 函數,來注冊點擊事件,即使在注冊事件時節點不存在也一樣有效:
$(document.body).on('click', '#showbox', function(event) {
$(this).hide();
});
Step7:點擊大圖的左右部分
現在我們要實現點擊圖片的右半部分,可以導航到下一張圖片;相反,如果點擊大圖的左半部分,則導航到上一張圖片。
為了實現這個效果,我們需要知道當前點擊的是圖片的哪半部分。來看下實現這一功能需要了解的知識:
- 當前點擊的元素 event.target
- 元素左上角偏離當前文檔左上角的位置,使用 jQuery 提供的 offset 函數
- 元素的寬度(包含 padding + border),使用 outerWidth 函數
- 當前點擊的位置在 X 軸的坐標 event.pageX
$(document.body).on('click', '#showbox', function(event) {
var targetEl = $(event.target);
if(targetEl.is('img')) {
var imageLeft = targetEl.offset().left;
var imageHalfX = imageLeft + targetEl.outerWidth() / 2;
if(event.pageX > imageHalfX) {
alert('click right part');
} else {
alert('click left part');
}
} else {
$(this).hide();
}
});
Step8:緩存頁面上所有的大圖
下面就需要知道,相對於當前展示的圖片,上一張圖片和下一張圖片分別是什么?
我們使用兩個函數來獲取即將展示的圖片,從而完整主題的JavaScript代碼,如下所示:
$(document.body).on('click', '#showbox', function(event) {
var targetEl = $(event.target);
if(targetEl.is('img')) {
var imageLeft = targetEl.offset().left;
var imageHalfX = imageLeft + targetEl.outerWidth() / 2;
var imageUrl = targetEl.attr('src');
var nextImageUrl;
if(event.pageX > imageHalfX) {
nextImageUrl = getNextImageUrl(imageUrl);
} else {
nextImageUrl = getPrevImageUrl(imageUrl);
}
if(nextImageUrl) {
targetEl.attr('src', nextImageUrl);
}
} else {
$(this).hide();
}
});
為了對頁面上所有的圖片進行精確定位,我需要一個緩存數組來記錄這些圖片:
var cachedImageUrls;
然后定義一個函數,來初始化這個數組,為了避免多次初始化,我們進行了非空判斷:
function cacheImageUrls() {
if(!cachedImageUrls) {
cachedImageUrls = $('.showit').map(function() {
return $(this).attr('href');
});
}
}
在此,jQuery 的 map 函數為我們提供了很大的便利,map 函數將一個 jQuery 對象映射為數組,函數內的 return 確定了數組中的每一項。
在執行完這個函數后,cachedImageUrls 內數據如下所示:
["images/1.jpg", "images/2.jpg", "images/3.jpg", "images/4.jpg", "images/5.jpg", "images/6.jpg"]
Step9:獲取上一張圖片和下一張圖片
拿到頁面上所有的大圖數組后,我們可以很方便的計算出當前圖片的上一張或者下一張圖片,注意做下數組的邊界檢查就行了:
function getNextImageUrl(imageUrl) {
cacheImageUrls();
var imageUrlIndex = $.inArray(imageUrl, cachedImageUrls);
if(imageUrlIndex >= 0) {
imageUrlIndex++;
if(imageUrlIndex >= cachedImageUrls.length) {
imageUrlIndex = 0;
}
return cachedImageUrls[imageUrlIndex];
}
}
注:jQuery 提供的 inArray 函數用來查找某項元素在數組中的索引,如果返回值小於零,則數組中不存在此項元素。
Step10:完整的JavaScript代碼
最后,來看下完整的 JavaScript 代碼:
$(function() {
$('.showit').click(function(event) {
var largeImageUrl = $(this).attr('href');
var boxEl = $('#showbox');
if(!boxEl.length) {
boxEl = $('<div>', {
id: 'showbox',
html: '<img/>'
}).appendTo(document.body);
}
boxEl.find('img').attr('src', largeImageUrl);
boxEl.show();
event.preventDefault();
});
var cachedImageUrls;
function cacheImageUrls() {
if(!cachedImageUrls) {
cachedImageUrls = $('.showit').map(function() {
return $(this).attr('href');
});
}
}
function getNextImageUrl(imageUrl) {
cacheImageUrls();
var imageUrlIndex = $.inArray(imageUrl, cachedImageUrls);
if(imageUrlIndex >= 0) {
imageUrlIndex++;
if(imageUrlIndex >= cachedImageUrls.length) {
imageUrlIndex = 0;
}
return cachedImageUrls[imageUrlIndex];
}
}
function getPrevImageUrl(imageUrl) {
cacheImageUrls();
var imageUrlIndex = $.inArray(imageUrl, cachedImageUrls);
if(imageUrlIndex >= 0) {
imageUrlIndex--;
if(imageUrlIndex < 0) {
imageUrlIndex = cachedImageUrls.length - 1;
}
return cachedImageUrls[imageUrlIndex];
}
}
$(document.body).on('click', '#showbox', function(event) {
var targetEl = $(event.target);
if(targetEl.is('img')) {
var imageLeft = targetEl.offset().left;
var imageHalfX = imageLeft + targetEl.outerWidth() / 2;
var imageUrl = targetEl.attr('src');
var nextImageUrl;
if(event.pageX > imageHalfX) {
nextImageUrl = getNextImageUrl(imageUrl);
} else {
nextImageUrl = getPrevImageUrl(imageUrl);
}
if(nextImageUrl) {
targetEl.attr('src', nextImageUrl);
}
} else {
$(this).hide();
}
});
});
