問題討論區


【JavaScript 語法】文章精華區


【教學】 [jQuery]jQuery 版的 Nike 首頁產品展示



[jQuery]jQuery 版的 Nike 首頁產品展示
飛肯老師
註冊日期:
2009/2/15 16:27
留言: 106
昨天梅干傳了一個 Nike.com.tw 的網址過來,讓筆者以為梅干要轉行賣鞋或是透過他買鞋可以拿到流血價咧!結果是...看到了它首頁的產品展示效果蠻不錯的,想討論看看是否能用 jQuery 來做出類似的功能。

Open in new window


稍微玩一下 Nike 的效果時會發現,產品項目的排列是左右都是小圖,只有中間顯示的是大圖。而當點擊右邊的產品時,全部的項目會往左移動,若是點擊左邊的產品時,則是往右移動。中間較大的區塊是顯示所點擊到的項目。另外,左右兩邊的項目預設是呈現半透明的效果,當滑鼠移上去時才會變成不透明。且當左右兩邊項目移動時,此時也是變成不透明的。

總結一下要實現的功能:
1.產品項目的排列要變程左右小圖,中間大圖的樣式。
2.點擊左邊項目就整個往右移;點擊右邊項目就整個往左移。中間區塊就移到所點擊的項目。
3.左右項目預設是半透明,當滑鼠移到某項目時才變成不透明,且當點擊後移動時也是不透明。

為了程式方便撰寫,筆者就把它設計成使用 3 組 ul 來當產品項目清單:

Open in new window


圖中所看到的都是獨立的一組 ul 元素,雖然每一組的第一個項目都是不一樣的,但這樣當大家都往前左或是往右移動時是能一致的。只要把它們組起來的話就會變成:

Open in new window


接著就動手來設計 HTML 及 CSS 囉:


<body>
    <
div class="nike">
        <
ul>
            <
li><a href="#"><img src="small01.gif" /></a></li>
            <
li><a href="#"><img src="small02.gif" /></a></li>
            <
li><a href="#"><img src="small03.gif" /></a></li>
            <
li><a href="#"><img src="small04.gif" /></a></li>
            <
li><a href="#"><img src="small05.gif" /></a></li>
        </
ul>
    </
div>
</
body>


一開始只是原始的 ul 產品項目,筆者等等會透過 jQuery 來產生需要的 3 組 ul 並放在 nike_left, nike_right 及 nike_main 區塊中。


ul
, li {
    
margin: 0;
    
padding: 0;
    list-
style: none;
}
a img {
    
border: none;
}
.
nike {
    
width: 300px;
    
height: 100px;
    
position: relative;
}
.
nike div ul {
    
width: 9999px;
    
position: absolute;
}
.
nike div ul li {
    
float: left;
}
.
nike div ul li a {
    
display: block;
    
width: 50px;    /* 小圖的寬 */
    
height: 50px;    /* 小圖的高 */
}
.
nike .nike_left {
    
position: absolute;
    
left: 0;
    
top: 25px;
    
width: 100px;    /* 小圖的寬 * 2 */
    
height: 50px;
    
overflow: hidden;
    
border: solid 1px #fff;
}
.
nike .nike_right {
    
position: absolute;
    
right: 0;
    
top: 25px;
    
width: 100px;    /* 小圖的寬 * 2 */
    
height: 50px;
    
overflow: hidden;
    
border: solid 1px #fff;
}
.
nike .nike_main {
    
position: absolute;
    
left: 100px;    /* 小圖的寬 * 2 */
    
top: 0;
    
width: 100px;    /* 大圖的寬 * 1 */
    
height: 100px;
    
overflow: hidden;
}
.
nike .nike_main ul li a {
    
width: 100px;    /* 大圖的寬 */
    
height: 100px;    /* 大圖的寬 */
}


再來就要打起精神仔細看了喔,筆者要先用 jQuery 來產生 ul 清單後再一一綁定其事件:


$(function(){
    
// 先取得 .nike 及原始的 ul 項目
    // 接著產生三組 div 並各自包一個 ul 項目
    // 再來取得一些額外的參數、小圖及大圖的名稱
    
var $nike = $('.nike'),
        
$source = $nike.children('ul').remove(),
        
$leftUl = $('<div class="nike_left"><ul></ul></div>').children(),
        
$rightUl = $('<div class="nike_right"><ul></ul></div>').children(),
        
$mainUl = $('<div class="nike_main"><ul></ul></div>').children(),
        
$sourceLi = $source.children(),
        
_liStr = $source.html(),
        
_itemLen = $sourceLi.length,
        
_middle = Math.ceil(_itemLen / 2),
        
_small = /small/ig,
        
_big = 'big',
        
_smallWidth = 50, _bigWidth = 100;

    
// 幫左邊 ul 清單加入 li 項目
    
$leftUl.append(_liStr + getLiItem($sourceLi, 0, _middle));
    
// 幫右邊 ul 清單加入 li 項目
    
$rightUl.append(getLiItem($sourceLi, _middle, _itemLen) + _liStr + getLiItem($sourceLi, 0, _itemLen - _middle));
    
// 幫中間 ul 清單加入 li 項目
    
$mainUl.append((getLiItem($sourceLi, _middle - 1, _itemLen) + _liStr).replace(_small, _big));
    
// 把 ul 清單部份都加到 .nike 中
    
$nike.append($leftUl.parent(), $rightUl.parent(), $mainUl.parent());

    
// 幫右邊 ul li a 加上 click 事件並產生 0.5 的透明度
    // 當點擊到時往左移動項目
    
$rightUl.find('li a').click(function(){
        
move(($(this).parent().index() + 1) % $rightUl.children().length);

        return
false;
    }).
fadeTo(200, 0.5);

    
// 幫左邊 ul li a 加上 click 事件並產生 0.5 的透明度
    // 當點擊到時往右移動項目
    
$leftUl.find('li a').click(function(){
        var
_index = $(this).parent().index();
        if(
_index<=1){
            
$leftUl.add($rightUl).css('left', _itemLen * _smallWidth * -1);
            
$mainUl.css('left', _itemLen * _bigWidth * -1);
            
_index += _itemLen;
        }
        
_index = (_index - (_itemLen - _middle)) % $leftUl.children().length;
        
move(_index);

        return
false;
    }).
fadeTo(200, 0.5);

    
// 幫左右兩邊的 ul li a 加上 hover 事件
    // 當滑鼠移到項目時就變成不透明;移出則再變成 0.5 的透明度
    
$rightUl.add($leftUl).find('li a').hover(function(){
        $(
this).fadeTo(200, 1);
    }, function(){
        $(
this).fadeTo(200, 0.5);
    });

    
// 控制移動的函式
    
function move(i){
        
// 移動左右清單
        // 移動時變成不透明
        
$leftUl.add($rightUl).stop(false, true).animate({
            
left: i * _smallWidth * -1
        
}, changeLeft).find('li a').css('opacity', 1);

        
// 移動中間清單
        
$mainUl.stop(false, true).animate({
            
left: i * _bigWidth * -1
        
}, changeLeft);
    }

    
// 當完成移動後的處理函式
    
function changeLeft(){
        var
$this = $(this),
            
dis = $this.parent().attr('className') == 'nike_main' ? _bigWidth : _smallWidth,
            
i = (parseInt($this.css('left'), 10) || 0) / dis * -1;

        
// 處理左右清單的位移
        
if(i >= _itemLen){
            $(
this).css('left', dis * (i - 5) * -1);
        }

        
// 把左右清單的 li a 變成 0.5 的透明度
        
if(dis==_smallWidth){
            $(
this).find('li a').css('opacity', 0.5);
        }
    }

    
// 組成 li 項目的函式
    
function getLiItem(source, startIndex, endIndex){
        var
rtvl = '';
        for(var
i=startIndex;i<endIndex;i++){
            
rtvl += '<li>' + source.eq(i).html() + '</li>';
        }
        return
rtvl;
    }
});


程式碼雖然看起來很長,但基本上就是先產生 3 組區塊及清單,然後加上 click 及移動的事件而已。當完成後就能看到很類似 Nike 的陽春畫面了:

Open in new window


各位可以試著玩看看,看是否有達到一開始筆者所預訂的那幾項功能需求!接著更大的難題來了,要如何幫它加上美美的外框呢?

筆者這邊把外框當成是遮罩的一種,因此只要讓遮罩能在最上層並中空的話,這樣就有加上外框的效果了:


/* .mask 為遮罩用的 div */
.nike .mask {
    
position: absolute;
    
left: 0;
    
top: 0;
    
width: 300px;
    
height: 100px;
    
background: transparent url(mask.png);    /* 遮罩圖片 */
    
z-index: 2;
}
.
nike .fake {
    
z-index: 3;
}


利用設定 z-index 的方式來達到階層的控制,但 IE 6 不支援透明的 PNG24 圖檔,所以...升級吧!現在已經有了 .mask 樣式了,接下來一樣是利用程式來加上它並做一些 Magic 的處理:


$(function(){
    
// 先取得 .nike 及原始的 ul 項目
    // 接著產生三組 div 並各自包一個 ul 項目
    // 再來取得一些額外的參數、小圖及大圖的名稱
    
var $nike = $('.nike'),
        
$source = $nike.children('ul').remove(),
        
$leftUl = $('<div class="nike_left"><ul></ul></div>').children(),
        
$rightUl = $('<div class="nike_right"><ul></ul></div>').children(),
        
$mainUl = $('<div class="nike_main"><ul></ul></div>').children(),
        
$sourceLi = $source.children(),
        
_liStr = $source.html(),
        
_itemLen = $sourceLi.length,
        
_middle = Math.ceil(_itemLen / 2),
        
_small = /small/ig,
        
_big = 'big',
        
_smallWidth = 50, _bigWidth = 100;

    
// 幫左邊 ul 清單加入 li 項目
    
$leftUl.append(_liStr + getLiItem(0, _middle));
    
// 幫右邊 ul 清單加入 li 項目
    
$rightUl.append(getLiItem(_middle, _itemLen) + _liStr + getLiItem(0, _itemLen - _middle));
    
// 幫中間 ul 清單加入 li 項目
    
$mainUl.append((getLiItem(_middle - 1, _itemLen) + _liStr).replace(_small, _big));
    
// 把 ul 清單部份都加到 .nike 中
    
$nike.append($leftUl.parent(), $rightUl.parent(), $mainUl.parent());
    
// 加入遮罩 .mask
    
$nike.append('<div class="mask"></div>');
    
// 加入控制用的遮罩 ul
    
$nike.append($leftUl.parent().clone().addClass('fake'), $rightUl.parent().clone().addClass('fake'), $mainUl.parent().clone().addClass('fake'));
    
// 隱藏控制用的遮罩 ul 中的圖片
    
$nike.find('.fake img').css('opacity', 0);
    
// 幫左右兩邊的 ul li a 加上 0.5 的透明度
    
$rightUl.add($leftUl).find('li a').fadeTo(200, 0.5);

    
// 幫控制用的右邊遮罩 ul li a 加上 click 事件
    // 當點擊到時往左移動項目
    
$('.nike_right.fake').find('li a').click(function(){
        
move(($(this).parent().index() + 1) % $rightUl.children().length);
        return
false;
    });

    
// 幫控制用的左邊遮罩 ul li a 加上 click 事件
    // 當點擊到時往右移動項目
    
$('.nike_left.fake').find('li a').click(function(){
        var
_index = $(this).parent().index();
        if(
_index<=1){
            
$leftUl.add($rightUl).add($('.nike_right.fake ul, .nike_left.fake ul')).css('left', _itemLen * _smallWidth * -1);
            
$mainUl.add($('.nike_main.fake ul')).css('left', _itemLen * _bigWidth * -1);
            
_index += _itemLen;
        }
        
move((_index - (_itemLen - _middle)) % $leftUl.children().length);
        return
false;
    });

    
// 幫控制用的左右兩邊遮罩的 ul li a 加上 hover 事件
    // 當滑鼠移到項目時就變成不透明;移出則再變成 0.5 的透明度
    
$('.nike_right.fake, .nike_left.fake').find('li a').hover(function(){
        var
$this = $(this);
        (
$this.parents('div').attr('className').indexOf('nike_right')>-1 ? $rightUl : $leftUl).children('li').eq($this.parent().index()).children().fadeTo(200, 1);
    }, function(){
        var
$this = $(this);
        (
$this.parents('div').attr('className').indexOf('nike_right')>-1 ? $rightUl : $leftUl).children('li').eq($this.parent().index()).children().fadeTo(200, 0.5);
    });

    
// 控制移動的函式
    
function move(i){
        
// 移動左右清單
        // 移動時變成不透明
        
$leftUl.add($rightUl).add($('.nike_right.fake ul, .nike_left.fake  ul')).stop(false, true).animate({
            
left: i * _smallWidth * -1
        
}, changeLeft).find('li a').css('opacity', 1);;

        
// 移動中間清單
        
$mainUl.add($('.nike_main.fake ul')).stop(false, true).animate({
            
left: i * _bigWidth * -1
        
}, changeLeft);
    }

    
// 當完成移動後的處理函式
    
function changeLeft(){
        var
$this = $(this),
            
dis = $this.parent().attr('className').indexOf('nike_main')>-1 ? _bigWidth : _smallWidth,
            
i = (parseInt($this.css('left'), 10) || 0) / dis * -1;

        
// 處理左右清單的位移
        
if(i >= _itemLen){
            $(
this).css('left', dis * (i - _itemLen) * -1);
        }

        
// 把左右清單的 li a 變成 0.5 的透明度
        
if(dis==_smallWidth){
            $(
this).find('li a').css('opacity', 0.5);
        }
    }

    
// 組成 li 項目的函式
    
function getLiItem(startIndex, endIndex){
        var
rtvl = '';
        for(var
i=startIndex;i<endIndex;i++){
            
rtvl += '<li>' + $sourceLi.eq(i).html() + '</li>';
        }
        return
rtvl;
    }
});


嘿~~快來看看效果變成怎樣:

Open in new window


是不是變的更有質感的呢!各位只要把圖片及遮罩替換後,就能有屬於自己的產品展示功能囉。

範例瀏覽:
http://demonstration.abgne.tw/jquery/0019/0019_1.html
http://demonstration.abgne.tw/jquery/0019/0019_2.html
http://demonstration.abgne.tw/jquery/0019/0019_3.html


以上內容於2010-03-04 14:03 發表在 http://abgne.tw/jquery/apply-jquery/jquery-nike-gallery.html

2010/3/11 9:43
 









[高級搜索]


 

課程首頁】 【最新開課時間表】 【範例教學分享區】 【交流討論區】 【企業包班】 【詢問課程】 【合作提案】 【誠徵講師

 

【飛肯設計學苑】 台北市公園路 30-1 號 5 樓 聯絡電話:(02)2370-1122 / 0925-014-000 信箱:flycan@flycan.com.tw
服務時間:(平日)下午 2 點 ~ 晚上 10 點 / (假日)早上 9 點 ~ 下午 5 點

 

台北市短期補習班立案 第 6631 號

TOP

【 Flycan.com 】 Powered by XOOPS