摘要:鼠標放到輪播圖的圖片上時不再自動輪播并且左右箭頭顯示出來,鼠標移開時左右箭頭隱藏掉并且自動輪播。核心原理清除定時器,綁定事件,重構下代碼封裝出往右往左輪播函數和自動輪播函數。
需求與分析
需求:
循環無縫自動輪播五張圖,按左右箭頭可以手動切換圖片,鼠標點擊輪播圖下面按鈕 1 2 3 4 5會跳轉到對應的第1 2 3 4 5張圖片。鼠標放到輪播圖的圖片上時不再自動輪播并且左右箭頭顯示出來,鼠標移開時左右箭頭隱藏掉并且自動輪播。
效果圖:
分析:
布局:準備七張圖片實現所謂的無縫輪播,固定七張圖片的寬高,下面假設為600px*400px。假設html分為三個區:圖片區、按鈕區、箭頭區。然后用個div包住這三個區并且固定該div的寬高也為600*400。
樣式:左右居中、距離頁面頂部100px顯示。五個按鈕為圓形的,并且輪播到哪張圖或者點到哪個按鈕時,該按鈕顏色變化。其余的小樣式具體寫代碼的時候佛系添加。
JS腳本:就說明一點圖的擺放位置,其余寫到那部分代碼的時候再說。
七張圖中,有兩張是和那不同的五張圖片中的第一張、第五張相同的。其中和五張不同圖中和第一張相同的圖放置在七張圖片中第七張,和五張不同圖中和第五張相同的圖放置在七張圖片中第一張。原因寫到那部分代碼時會再說
給a標簽加 javascript:void (0);是為了不讓a標簽跳轉。
主要目的:給總div、圖片區按鈕區div、圖片、按鈕、左右箭頭定義寬高,讓七個圖片并排顯示,五個按鈕位于圖片底部居中顯示,兩個箭頭分別到左右兩邊的適中位置顯示。
/* 清除默認樣式 */ *{ margin: 0; padding: 0; text-decoration: none; } /* 總div */ div.container{ position: relative; width: 600px; height: 400px; margin: 100px auto 0 auto; box-shadow: 0 0 5px aqua; overflow: hidden; } /* 圖片區 */ div.container div.wrap{ position: absolute; width: 4200px; height: 400px; z-index: 1; } div.container div.wrap img{ width: 600px; height: 400px; float: left; } /* 按鈕區 */ div.container div.button{ position: absolute; right: 225px; bottom: 15px; width: 150px; height: 20px; z-index: 2; text-align: center; } div.container div.button span{ margin-left: 5px; display: inline-block; width: 20px; height: 20px; border-radius: 50%; background-color: greenyellow; text-align: center; color: white; cursor: pointer; opacity: 0.6; } /* 輪播到哪張圖,哪個按鈕有這個效果,與其他按鈕有個區別。 */ div.container div.button span.on{ opacity: 1; } /* 箭頭區 */ div.container .jt{ position: absolute; top: 40%; color:greenyellow; padding: 0px 14px; font-size: 55px; text-align: center; z-index: 2; display: none; } div.container .jt_left{ left: 10px; } div.container .jt_right{ right: 10px; } div.container:hover .jt{ display: block; opacity: 0.4; } div.container .jt:hover{ opacity: 1; }
為了讓剛進頁面第一張圖顯示的是1.jpg,所以在圖片區圖里面加個行內樣式,讓默認打開頁面顯示這個圖:
此時效果是這樣,當鼠標移動到圖片上、箭頭處都有一些樣式:
第一步:實現圖片自動切換
封裝兩個函數:next()、prev()函數,分別對應向右輪播和向左輪播,此時調用哪個函數,就可以向哪個方向一張圖片一張圖片得切換輪播。
var wrap = document.getElementsByClassName("wrap")[0]; var newLeft = -600; function next() { setInterval(function(){ if(newLeft == -2400){ newLeft = 0; }else{ newLeft = parseInt(wrap.style.left) - 600; } wrap.style.left = newLeft + "PX"; },1000) } function prev() { setInterval(function(){ if(newLeft == -600){ newLeft = -3000; }else{ newLeft = parseInt(wrap.style.left) + 600; } wrap.style.left = newLeft + "PX"; },1000) }
第二步:讓輪播的時候各個圖片有運動軌跡地切換,而不是硬生生地從一張圖片變到另一張圖片。
這里需要用到我封裝好的一個運動函數startMove(),做成工具使用:
function getStyle(obj, attr){ if(obj.currentStyle){ return obj.currentStyle[attr]; }else{ return getComputedStyle(obj, false)[attr]; } } //運動框架 startMove函數 function startMove(obj,json,fn){ clearInterval(obj.timer); //開啟定時器 obj.timer = setInterval(function(){ var flag = true; //遍歷json for (var attr in json) { //取當前值 iCur var iCur = 0; if (attr == "opacity") { iCur = Math.round(parseFloat(getStyle(obj, attr))*100); }else{ iCur = parseInt(getStyle(obj, attr)); } //算速度:iSpeed //目標值:json[attr] var iSpeed = (json[attr]-iCur)/8; iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); //檢測停止 if (iCur != json[attr]) { flag = false } if (attr == "opacity") { obj.style.filter = "alpha(opacity:"+iCur+iSpeed+")"; obj.style.opacity = (iCur+iSpeed)/100; }else{ obj.style[attr] = iCur + iSpeed + "px"; } } if (flag) { clearInterval(obj.timer); if (fn) {fn();} } },30) }
這個封裝的運動函數這里,加上我的注釋還看不懂代碼的,可以去看看這個視頻,這講師講得很清楚:JS動畫效果
然后利用這個原理:當圖片往右輪播到第六張的時候,馬上讓第一張呈現出來,緊接著調用封裝好的運動函數讓從第一張圖運動切換到第二張。往左輪播時也是一樣的道理,當輪播到第一張的時候馬上讓第六張呈現出來,緊接著從第六張運動到第五張。這樣子從視覺上看來就是五張圖片一直循環無縫輪播下去的
這是也為什么要用七張圖片,并且第一張圖片和第六張一樣,第七張和第二張一樣的原因。
代碼如下:
var wrap = document.getElementsByClassName("wrap")[0]; var newLeft = -600; function next() { setInterval(function () { if (newLeft == -3000) { newLeft = 0; wrap.style.left = newLeft + "px"; } newLeft -= 600; startMove(wrap, { "left": newLeft }) // wrap.style.left = newLeft + "PX"; }, 3000) } function prev() { setInterval(function () { if (newLeft == 0) { newLeft = -3000; wrap.style.left = newLeft + "px"; } newLeft += 600; startMove(wrap, { "left": newLeft }); }, 3000) }
第三步:使當鼠標移到圖片上時,停止自動輪播而讓點擊幾次左右箭頭來控制往左右一張一張地輪播幾張。
核心原理:清除定時器,綁定click、onmouseenter、onmouseleave事件,重構下代碼封裝出往右往左輪播函數和自動輪播函數。
往右輪播函數:
function next() { if (newLeft == -3000) { newLeft = 0; wrap.style.left = newLeft + "px"; } newLeft -= 600; startMove(wrap, { "left": newLeft }); }
往左輪播函數:
function prev() { if (newLeft == 0) { newLeft = -3000; wrap.style.left = newLeft + "px"; } newLeft += 600; startMove(wrap, { "left": newLeft }); }
自動播放函數:
var timer = null; function autoPlay() { timer = setInterval(function () { next(); }, 2000) } /* 自動播放 */
綁定各個事件:
container.addEventListener("mouseenter", function () { clearInterval(timer); }, false) container.addEventListener("mouseleave", function () { autoPlay(); }, false) left.addEventListener("click", function () { prev(); }) right.addEventListener("click", function () { next(); })
第四步:
處理按鈕,使剛進頁面時,第一個按鈕有span元素中類為"on"的效果。
接下來,實現視覺上輪播到哪張圖了,就對應哪個按鈕有類為"on"的效果。
最后,當你點到哪個按鈕時,該按鈕有類為"on"的效果,并且跳轉到視覺上的第幾張圖。
封裝個處理按鈕的函數,功能是給每個按鈕的類名設置為空,然后當視覺上移動到第A張圖時,就讓此時這第A個按鈕的類型為"on"。
所以需要設置個哨兵index監聽這是視覺上第幾張圖,然后為這張圖對應的按鈕添加"on"類:
//處理按鈕 var index = 0; var len = dot.length; function setCurrentDot(){ for (var m = 0; m < len; m++){ dot[m].className = ""; } dot[index].className = "on"; } setCurrentDot();
此時調用了這個函數的話,就等于剛進入頁面的時候默認顯示的第一張圖片也是默認讓第一個按鈕有"on"類的效果。
那怎么讓當視覺上移動到第A張圖時,就讓此時這第A個按鈕的類型為"on"呢?
可以在輪播一次的函數里加入修改index哨兵的值并且調用setCurrentDot()函數。在next()中:
index++; if(index === 5){ index = 0; } setCurrentDot();
在prev()中:
index--; if(index === -1){ index = 4; } setCurrentDot();
最后,實現點到哪個按鈕時,該按鈕有類為"on"的效果,并且跳轉到視覺上的第幾張圖。
核心思路:當點擊該按鈕時,比如點了第三個按鈕,那么此時應該顯示的圖片應該是視覺上第三張圖片也就是七張圖片中的第四張,第四張對應的wrap的left為-1800px,然后找出對應的規律,此時的newLeft就應該為:-600 * (x + 1)。那么不管在點擊按鈕前已經輪播到哪里了,只要在點擊后,使用運動函數startMove()移動到這個newLeft位置處就行了。按例子來說此時的哨兵index也等于3,因為點了第幾個按鈕肯定就第幾個按鈕有"on"類咯。
根據核心思路寫出代碼為(這里需要注意綁定事件時的閉包問題):
// 點到哪個按鈕時,該按鈕有類為"on"的效果,并且跳轉到視覺上的第幾張圖。 for (var s = 0; s < len; s++){ (function(s){ dot[s].addEventListener("click",function(){ newLeft = -600 * (s + 1); startMove(wrap,{"left":newLeft}); index = s; setCurrentDot(); },false) }(s)) }
寫到這里,所以需求就做完了。
最后思路就是這樣,重要的不是代碼,是分析邏輯。
源碼已傳到github,覺得對您有幫助的,麻煩點個star,謝謝~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/53062.html
摘要:鼠標放到輪播圖的圖片上時不再自動輪播并且左右箭頭顯示出來,鼠標移開時左右箭頭隱藏掉并且自動輪播。核心原理清除定時器,綁定事件,重構下代碼封裝出往右往左輪播函數和自動輪播函數。 需求與分析 需求:循環無縫自動輪播五張圖,按左右箭頭可以手動切換圖片,鼠標點擊輪播圖下面按鈕 1 2 3 4 5會跳轉到對應的第1 2 3 4 5張圖片。鼠標放到輪播圖的圖片上時不再自動輪播并且左右箭頭顯示出來,...
摘要:鼠標放到輪播圖的圖片上時不再自動輪播并且左右箭頭顯示出來,鼠標移開時左右箭頭隱藏掉并且自動輪播。核心原理清除定時器,綁定事件,重構下代碼封裝出往右往左輪播函數和自動輪播函數。 需求與分析 需求:循環無縫自動輪播五張圖,按左右箭頭可以手動切換圖片,鼠標點擊輪播圖下面按鈕 1 2 3 4 5會跳轉到對應的第1 2 3 4 5張圖片。鼠標放到輪播圖的圖片上時不再自動輪播并且左右箭頭顯示出來,...
摘要:前言做項目就難免會開發交互效果或者特效,而我最近開發的項目一直在使用,開發技術棧方面,理所當然就使用了開發,過程中發現使用開發特效,和的思維方式不一樣,但是比簡單一點點。 1.前言 做項目就難免會開發交互效果或者特效,而我最近開發的項目一直在使用vue,開發技術棧方面,理所當然就使用了vue+css3開發,過程中發現使用vue+css3開發特效,和javascript/jquery+c...
摘要:前言做項目就難免會開發交互效果或者特效,而我最近開發的項目一直在使用,開發技術棧方面,理所當然就使用了開發,過程中發現使用開發特效,和的思維方式不一樣,但是比簡單一點點。 1.前言 做項目就難免會開發交互效果或者特效,而我最近開發的項目一直在使用vue,開發技術棧方面,理所當然就使用了vue+css3開發,過程中發現使用vue+css3開發特效,和javascript/jquery+c...
閱讀 3460·2019-08-30 13:15
閱讀 1400·2019-08-29 18:34
閱讀 822·2019-08-29 15:18
閱讀 3480·2019-08-29 11:21
閱讀 3246·2019-08-29 10:55
閱讀 3688·2019-08-26 10:36
閱讀 1868·2019-08-23 18:37
閱讀 1816·2019-08-23 16:57