你一定用過書簽,也一定給你的書本加過書簽,那麼你見過書簽式的導航嗎? 你一定見過手風琴,也一定知道彈奏手風琴時的它的外形變化,那麼你見過手風琴式的導航嗎? 如果沒有,請往下看:
前面的話:
這篇博文先通過Javascript做一個簡單的手風琴效果,讓大家對手風琴效果有一定的了解;緊接著,我們換jquery做類似的手風琴效果。前面的兩個例子都很簡單,接下來要放大招了,我想用JQ或是原生的JS去做類似淘寶網中用到的手風琴效果。繼續回到書簽問題,既然JQ和JS都能實現那麼炫酷的效果,我們用CSS3能不能做出手風琴效果的書簽來呢?
用Javascript做一個簡單的手風琴效果:
話不多說,我們先上代碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> *{ margin: 0; padding: 0; } body{ background-color: rgba(0,0,0,.8); } div{ margin: 20px auto; } #c { width: 500px; height: 300px; overflow: hidden; } p { float: left; width: 20px; height: 300px; } </style> </head> <body> <div id="c"> <p style="background:#9cf;width:420px;">1</p> <p style="background:#f9c;">2</p> <p style="background:#c9f;">3</p> <p style="background:#cf9;">4</p> <p style="background:#9fc;">5</p> </div> </body> </html>
效果:
分析:在不使用JS的情況下,我們只能通過改變p的寬度,來模仿手風琴效果,然後我們忽略人為因素的影響,讓其在鼠標經過每個p時,該p的寬度發生變化。
這裡我們知道了要改變p的寬度,那麼接下來就簡單了,我們用前面介紹過的關於Javascript動畫的相關方法就可以得到我們想要的效果(點擊:Javascript動畫相關)。參考代碼如下:
function accordion() { var Div = document.getElementById('c'); var Divs = Div.getElementsByTagName('p'); var i = 0; var t = null; for(i = 0; i < Divs.length; i++) { Divs[i].index = i; Divs[i].onmouseover = function() { var index = this.index; if(t) { clearInterval(t); } t = setInterval(function() { var iWidth = 500; for(i = 0; i < Divs.length; i++) { if(index != Divs[i].index) { var iSpeed = (20 - Divs[i].offsetWidth) / 5; iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); Divs[i].style.width = Divs[i].offsetWidth + iSpeed + 'px'; iWidth -= Divs[i].offsetWidth; }; }; Divs[index].style.width = iWidth + 'px'; }, 30); }; } } accordion();
上面的代碼不做解釋,代碼運行後的結果點擊網址: http://sandbox.runjs.cn/show/daapxxo9 查看。
用jquery做類似的手風琴效果:
前面的效果是不是覺得很簡單,下面我們加一點點難度,有如下要求:
1、將前面的背景顏色換成圖片
2、增加文字
3、用jquery實現
先來完成我們的html代碼:
<div class="pic"> <ul> <li class="pic1"> <a href="javascript:;"> <div class="txt"> <p class="p1">作者:陳武</p> <p class="p2">效果:手風琴效果</p> </div> </a> </li> <li class="pic2"> <a href="javascript:;"> <div class="txt"> <p class="p1">作者:陳武</p> <p class="p2">效果:手風琴效果</p> </div> </a> </li> <li class="pic3"> <a href="javascript:;"> <div class="txt"> <p class="p1">作者:陳武</p> <p class="p2">效果:手風琴效果</p> </div> </a> </li> <li class="pic4"> <a href="javascript:;"> <div class="txt"> <p class="p1">作者:陳武</p> <p class="p2">效果:手風琴效果</p> </div> </a> </li> </ul> </div>
注意: <a href="javascript:;">的意思是屏蔽a標簽的默認動作
分析樣式:只有最後一張圖片顯示的是原始尺寸,其余的寬度都為100px,然後對我們的樣式進行修改,代碼如下:
* { margin: 0; padding: 0; font-family: "微軟雅黑"; list-style-type: none; } body { background-color: #000; } a { text-decoration: none; } header, footer { width: 1000px; height: 40px; margin: 0 auto; text-align: center; padding: 20px 0; color: #fff; } header p { text-align: right; } .pic { width: 1000px; height: 320px; margin-top: 60px; margin: 0 auto; border: 5px solid aqua; border-radius: 5px; overflow: hidden; } .pic1 { background: url(images/1.jpg) no-repeat; } .pic2 { background: url(images/2.jpg) no-repeat; } .pic3 { background: url(images/3.jpg) no-repeat; } .pic .pic4 { background: url(images/4.jpg) no-repeat; width: 700px; } .pic ul li { float: left; width: 100px; height: 320px; overflow: hidden; } .txt { background-color: rgba(0, 100, 200, .5); height: 320px; width: 100px; } .txt p { float: left; color: #fff; word-break: break-all; } .txt .p1 { font-size: 12px; width: 12px; padding: 30px 10px 0; } .txt .p2 { font-size: 16px; width: 16px; padding: 30px 10px 0; }
在我們運行上面的代碼前,我們應注意如下問題
注意一: 不在.pic4前加.pic只是設置的寬度為700會怎樣?(.pic4的權重不夠,導致該樣式被覆蓋掉了。)
注意二:如果我們不加no-repeat會怎樣?(自己當時疏忽忘了加no-repeat,圖片不能正常顯示,調試了好久)
注意三:在.pic裡面不加overflow: hidden;會怎樣?(到後面寫了JQ再調試的時候,發現圖片老是被擠下來)
接下來用Jquery方法就簡單了,我們直接用裡面的動畫方法animate就行了,代碼如下:
$(function() { $('.pic ul li').mouseover(function() { $(this).animate({ width: '700px' }, 1000).siblings().animate({ width: '100px' }, 1000); }); });
到這裡,我們發現一點點不足,鼠標經過的時候,動畫很僵硬,這時候,我們有沒有什麼方法能將我們的動畫看上去更流暢?
什麼?你說stop()方法?stop()方法是什麼東西,我好像不知道。【下面是我查到的關於stop()方法的一些知識】
stop()方法的格式如下:
stop( [clearQueue] , [gotoend])
該方法的功能是停止所選元素中正在執行的動畫,其中可選參數[clearQueue]是一個布爾值,表示是否停止正在執行的動畫。另外一個可選參數 [gotoend]也是一個布爾值,表示是否立即完成正在執行的動畫。
當stop()時:只中斷第一個動畫;
當stop(true)時:中斷所有動畫;
當stop(true,true)時:直接到達最終狀態。
與stop()方法對應的還有delay()方法,其格式如下:
delay( duration, [queueName])
該方法的功能是設置一個延遲值來推遲後續隊列中動畫的執行,其中參數為延遲時間的時間值,單位是毫秒。可選參數表示隊列名詞,即動畫隊列(如:slideToggle)。
在這裡我們需要用到的當然是stop(true)了,
在這裡我們需要用到的當然是stop(true)了,修改好代碼後,運行結果:
點擊網址即可查看:http://sandbox.runjs.cn/show/1l4u3w9d
用JQ或是JS仿淘寶也中用到的手風琴效果:
有了前面的基礎,後面的也沒那麼難了,只是教前面復雜了許多,廢話少說,這裡直接上代碼:
<div id="subject" class="home-subjects-v2"> <ul> <li> <a> <img src="img/1.jpg"> <div class="info"> <h3 style="color:#f62368">聚美妝</h3> <p>聚美妝1/2周年慶</p> <p class="price"><strong>1</strong><i>折起</i></p> <p class="more">進入專題搶購 > </p> </div> <s class="line"></s> <i class="mask"></i> </a> </li> <li class="big"> <a> <img src="img/2.jpg"> <div class="info"> <h3 style="color:#ff578a">Baby購</h3> <p>寶寶該換裝了,新品搶購</p> <p class="price"><strong>2.5</strong><i>折起</i></p> <p class="more">進入專題搶購 > </p> </div> <s class="line"></s> <i class="mask"></i> </a> </li> <li> <a> <img src="img/3.jpg"> <div class="info"> <h3 style="color:#6d3fa7">時裝團</h3> <p>時尚春裝,清新小潮搭配</p> <p class="price"><strong>1</strong><i>折起</i></p> <p class="more">進入專題搶購 > </p> </div> <s class="line"></s> <i class="mask"></i> </a> </li> <li> <a> <img src="img/4.jpg"> <div class="info"> <h3 style="color:#d61939">TV購</h3> <p>補血養顏 就這麼簡單</p> <p class="price"><strong>2.6</strong><i>折起</i></p> <p class="more">進入專題搶購 > </p> </div> <s class="line"></s><i class="mask"></i> </a> </li> <li> <a> <img src="img/5.jpg"> <div class="info"> <h3 style="color:#6f9400">聚新鮮</h3> <p>最純正的泰國香米</p> <p class="price"><strong>5</strong><i>折起</i></p> <p class="more">進入專題搶購 > </p> </div> <i class="mask"></i> </a> </li> </ul> </div>
對樣式進行修改,使其接近淘寶網中的效果,代碼如下:
body,ul,li,p {margin: 0;padding: 0} ul,ol {list-style: none;} .home-subjects-v2{height:128px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border:1px solid #d3d3d3;border-color:rgba(0,0,0,.12);overflow:hidden;width:938px;margin-top:12px;background:#fff} .home-subjects-v2 ul{width:1000px} .home-subjects-v2 li{width:156px;height:128px;float:left;overflow:hidden;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;-o-transition:all .1s linear;-ms-transition:all .1s linear;transition:all .1s linear} .home-subjects-v2 li *{-webkit-transition:all .1s linear;-moz-transition:all .1s linear;-o-transition:all .1s linear;-ms-transition:all .1s linear;transition:all .1s linear} .home-subjects-v2 li a{width:156px;height:128px;display:block;position:relative;cursor:pointer;text-decoration:none;overflow:hidden} .home-subjects-v2 li a:hover{position:absolute} .home-subjects-v2 li a:hover .mask{-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);opacity:0;-webkit-transition:opacity .2s ease-in;-moz-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;-ms-transition:opacity .2s ease-in;transition:opacity .2s ease-in} .home-subjects-v2 li img{height:72px;width:117px;position:absolute;bottom:0;right:-13px} .home-subjects-v2 li .line{height:128px;width:0;font-size:0;border-right:1px dashed #cacaca;position:absolute;right:0;top:4px} .home-subjects-v2 li .info{position:absolute;top:0;left:0;width:136px;padding:4px 10px} .home-subjects-v2 li .info h3{font-size:14px;font-weight:700} .home-subjects-v2 li .info p{color:#868686;font-size:12px;overflow:hidden;width:136px;height:22px;line-height:22px} .home-subjects-v2 li .info p.price{font-size:14px;font-style:italic;color:#fa2a5d;height:35px} .home-subjects-v2 li .info p.price strong{font-size:22px;font-family:Arial;padding-right:2px} .home-subjects-v2 li .info p.price i{font-size:14px} .home-subjects-v2 li .info p.more{display:none} .home-subjects-v2 .mask{height:128px;width:156px;display:block;position:absolute;top:0;left:0;background:#000;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);opacity:0;-webkit-transition:opacity .2s ease-in;-moz-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;-ms-transition:opacity .2s ease-in;transition:opacity .2s ease-in;_display:none!important} .home-subjects-v2 .big{width:314px} .home-subjects-v2 .big a{width:314px} .home-subjects-v2 .big img{width:195px;height:120px;right:0;bottom:0} .home-subjects-v2 .big .info{width:294px} .home-subjects-v2 .big .info h3{font-size:18px} .home-subjects-v2 .big .info p{font-size:14px;width:166px} .home-subjects-v2 .big .info p.price{font-size:16px;padding-top:7px} .home-subjects-v2 .big .info p.price strong{font-size:28px} .home-subjects-v2 .big .info p.price i{font-size:16px} .home-subjects-v2 .big .info p.more{display:block;font-size:12px;color:#ff2a5b} .home-subjects-v2 .big .mask{width:314px} .home-subjects-v2:hover .mask{-ms-filter:"alpha(Opacity=15)";filter:alpha(opacity=15);opacity:.15;-webkit-transition:opacity .2s ease-in;-moz-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;-ms-transition:opacity .2s ease-in;transition:opacity .2s ease-in}
在這裡,我們需要注意的有:
1、超出的部分隱藏(overflow:hidden)、超出的部分顯示(overflow:visible)、隱藏元素(display:none)、視覺隱藏元素(visibility:hidden),我們要區分這幾個概念
2、opacity透明度,在標准浏覽器和ie浏覽器中透明度是不一樣的,前面的簡單的程序沒考慮,但是我們應該時刻有這種意識。
3、虛線的實現方法:.line { position:absolute; right:0px; width:0px;height:128px;border:1px dashed #ccc;}由於只需要虛線邊框的效果,故該元素的寬度為0。
4、關於遮罩層。之前想到將整個大容器添加一個遮罩層,這種做法不可取。當鼠標懸停,大容器的遮罩層的透明度不為0,即便此時對單列表容器的遮罩層設置透明度也無法消除大容器的遮罩層所帶來的影響。正確的做法應該是,對每個列表使用遮罩層,在鼠標懸停時:.wrap:hover .mask{opacity:0.15}.wrap:hover .mask:hover{opacity:0}這樣做就不會出現疊加效應,因為都是對一個樣式進行的設置,這裡還要對比權值(汲取前面的經驗)。
下面我們用原生的Javascript方法來實現:
在寫之前,我們先理一下我們的思路,在前面的手風琴效果中我們只需要改變單一的寬度就行了,但是在這裡我們的要求就高了很多。在CSS部分,我們已經有了變換效果的雛形,我們將class="big"添加到任意li中,該li就會發生改變。知道這裡,我們接下來的做法又變得簡單了。如何修改li中的class?我的思路如下:
首先寫出一個主函數體獲取元素li -》 list,然後list進行for循環,在for循環中進行綁定bind的鼠標點擊事件,bind(list[i],"mouseover", mouseoverHandler);(mouseoverHandler 是mouseover的回調……)代碼如下:
function initList() { //取得每個列表項 var list = document.getElementsByTagName("li"); for(var i = 0; i < list.length; i++) { //對每個列表綁定鼠標懸停事件的監聽 bind(list[i], "mouseover", mouseoverHandler); } }
然後我們來寫事件的綁定,需要判斷是標准事件綁定還是ie事件綁定,然後執行不同的操作,代碼如下:
function bind(el, eventType, callback) { //標准事件綁定 if(typeof el.addEventListener === "function") { el.addEventListener(eventType, callback, false); } else if(typeof el.attachEvent === "function") { //ie事件綁定 el.attachEvent("on" + eventType, callback); } }
然後我們繼續寫鼠標懸停處理函數,代碼如下:
//鼠標懸停處理函數 function mouseoverHandler(e) { var target = e.target || e.srcElement; var list = document.getElementsByTagName("li"); for(var i = 0; i < list.length; i++) { //清空所有li元素的big list[i].className = ""; } //根據事件的冒泡原理,找到需要變更class的li元素 while(target.tagName != "LI" && target.tagName != "BODY") { target = target.parentNode; } //給當前元素加上class big target.className = "big"; }
最後我們將所有函數寫在window.onload裡面,別忘了調用initList();。
最終實現效果如圖:
可以點擊鏈接查看,鏈接:http://runjs.cn/detail/jtuihuj7
用Jquery方法來實現我們想要的效果:
從前面Jquery的例子我們可以看出,用Jquery方法要簡單些,我們按照Javascript的分析思路,來完成Jquery代碼,代碼如下:
function mouseover(e) { //獲取到li標簽 var list = $('#subject li'); //獲取到目標li標簽,進行添加或刪除操作 var target = $(e.target).parents('li'); list.removeClass('big'); target.addClass('big'); } (function() { var outer = $('#subject'); outer.find('li').on('mouseover', mouseover); })()
最終結果與Javascript方法的結果一樣,可以點擊鏈接查看,鏈接:http://runjs.cn/detail/sa6gthpa
用CSS3做書簽:
html部分代碼:
<div id="dise"> <pic class="demo"> <ul class="main_promo clearfix" id="main_promo"> <li> <input type="radio" name="radio-set" checked="checked" /> <div class="slide"> <a href="#"> <p>點<br />绛<br />唇<br />·<br />花<br />信<br />來<br />時</p> </a> </div> <div class="slide_img" style="background-image: url(imgs/1.jpg);"> <h4>點绛唇·花信來時</h4> <p class="p1">花信來時,恨無人似花依舊。<br />又成春瘦,折斷門前柳。<br />天與多情,不與長相守。<br />分飛後,淚痕和酒,占了雙羅袖。</p> <p class="p2"><span>譯文:</span>應花期而來的風喲,你雖來了,但人已離散去,全不像那花兒依舊。 人到春來瘦,等候著心上人,倚門盼歸,折斷了門前楊柳。 上天賦予了人多情的心,卻不肯給予長相守的機會。自你我分別後,伴隨我的,只是相思的淚、澆愁的酒,沾濕了我的雙羅袖。 </p> </div> </li> <li> <input type="radio" name="radio-set" /> <div class="slide"> <a href="#slide_two"> <p>鹧<br />鸪<br />天<br />·<br />守<br />得<br />蓮<br />開<br />結<br />伴<br />游</p> </a> </div> <div class="slide_img" style="background-image: url(imgs/2.jpg);"> <h4>鹧鸪天·守得蓮開結伴游</h4> <p class="p1">守得蓮開結伴游,約開萍葉上蘭舟。<br />來時浦口雲隨棹,采罷江邊月滿樓。<br /> 花不語,水空流,年年拚得為花愁。<br />明朝萬一西風動,爭向朱顏不耐秋。</p> <p class="p2"><span>譯文:</span>湖塘中長滿了浮萍,姑娘們相約來到湖中,一起撥開浮萍采蓮。來時,旭日初升,浦口水面上如煙的水汽,在長槳四周缭繞。采蓮後回到岸上,月光已照滿了高樓。 好花無語,流水無情,年年都為花落春去而傷愁。明天萬一西風驟然強勁,無奈蓮花抵抗不住秋寒,很快就會凋落。</p> </div> </li> <li> <input type="radio" name="radio-set" /> <div class="slide"> <a href="#slide_three"> <p>涼<br />州<br />詞<br />二<br />首<br />·<br />其<br />一</p> </a> </div> <div class="slide_img" style="background-image: url(imgs/3.jpg);"> <h4>涼州詞二首·其一</h4> <p class="p1">葡萄美酒夜光杯,<br />欲飲琵琶馬上催。<br /> 醉臥沙場君莫笑,<br />古來征戰幾人回?</p> <p class="p2"><span>譯文:</span>酒筵上甘醇的葡萄美酒盛滿在精美的夜光杯之中,歌伎們彈奏起急促歡快的琵琶聲助興催飲,想到即將跨馬奔赴沙場殺敵報國,戰士們個個豪情滿懷。 今日一定要一醉方休,即使醉倒在戰場上又何妨?此次出征為國效力,本來就打算馬革裹屍,沒有准備活著回來。 </p> </div> </li> <li> <input type="radio" name="radio-set" /> <div class="slide"> <a href="#slide_four"> <p>夜<br />雨<br />寄<br />北</p> </a> </div> <div class="slide_img" style="background-image: url(imgs/4.jpg);"> <h4>夜雨寄北</h4> <p class="p1">君問歸期未有期,<br />巴山夜雨漲秋池。 <br />何當共剪西窗燭,<br />卻話巴山夜雨時。</p> <p class="p2"><span>譯文:</span>您問歸期,歸期實難說准,巴山連夜暴雨,漲滿秋池。何時歸去,共剪西窗燭花,當面訴說,巴山夜雨況味。 </p> </div> </li> </ul> </pic> </div>
CSS部分代碼:
html { background: -webkit-radial-gradient(center, ellipse, #232323 0%, #000 100%); height: 100%; } #dise { width: 1010px; height: 380px; margin-left: auto; margin-right: auto; margin-top: 100px; background-color: rgba(255, 255, 255, 0.1); } .demo { position: absolute; margin-top: 20px; width: 1040px; margin-left: auto; margin-right: auto; } .main_promo li { position: relative; float: left; left: 0px; top: 0px; padding: 5px 0 5px 6px; overflow: hidden; } .main_promo div { float: left; } .slide a { position: relative; z-index: 1; display: block; width: 50px; height: 300px; border-radius: 0px; background-color: rgba(255, 255, 255, 0.1); transition: all 1.3s; } .slide p { /*設置字體*/ position: absolute; top: 20px; left: 10px; color: #A7170A; height: 20px; width: 100px; font-family: 方正啟體繁體; font-size: 20px; font-weight: bold; text-shadow: 2px 2px 4px rgba(0, 0, 0, .8); word-break: break-all; /*-webkit-transform: rotate(-90deg);*/ } .slide_img { overflow: hidden; width: 0; height: 0; /*此處的長寬設置不能省略,否則不能隱藏*/ transition: width 0.7s ease-in-out; } input[type="radio"] { /*radio和a重合,達到選擇的效果*/ position: absolute; left: 5px; z-index: 99; width: 50px; height: 300px; opacity: 0; } input:checked~ .slide a { opacity: 1; background: rgba(255, 255, 255, 0.1); /*按鈕閃光效果*/ } input:checked~ .slide_img { width: 692px; height: 300px; /*此處的長寬必須設置,否則不顯示*/ margin-left: 8px; } /*將背景顏色換成圖片,並在上面添加書簽,設置其css樣式*/ .slide_img h4 { font-size: 28px; font-weight: bold; background-color: rgba(100, 100, 100, .5); color: #000080; } .slide_img .p1 { background-color: rgba(255, 255, 255, .5); color: #000080; } .slide_img .p2 { background-color: rgba(0, 0, 0, .8); color: #00FFFF; } .slide_img .p2 span { font-size: 40px; font-weight: bold; }
具體實現效果截圖:
具體案例展示:http://sandbox.runjs.cn/show/u8dyr3hx
後面的話:
在用Javascript方法做仿淘寶手風琴效果是在網上找視頻學的,但是最終視頻裡面的代碼與實際運行結果不符,後面又在《Javascript高級程序設計上》專門看關於事件的部分內容,突然間覺得自己前面學習的太淺了,後面要抽時間把這一段給補上。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。