您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關原生JS如何改變透明度實現輪播效果的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
第一部分(html+css)
包含的知識有:positon定位。
最外層是一個div,它包含了所有的元素。這個輪播一共有三張圖片,這三張圖片包含在一個無序列表中。最外層的div還有兩個用來切換上一張圖片和下一張圖 片的子元素。這兩個子元素也是div,切換上一張圖片的div的id屬性為pre,切換下一張圖片的div的id屬性為next。最外層div的 position值為relative。包含圖片的無序列表的position為relative。無序列表中的li元素的positon屬性值為 absolute,這會讓li元素位于文檔流之外,所以如果不顯示的設置ul的高度,ul高度為零。但是我們不能用css去顯示設置ul的高度。因為需要 讓這個輪播的高度等于圖片的高度,并且要保證在不同分辨率的計算機上圖片的高寬比保持不變。在不同分辨率的計算機上圖片顯示出的高度和寬度是不一樣的。所 以我是通過js去設置ul的高度。因為ul的position的屬性值為relative,所以ul的高度會撐開外層div的高度。由于這個案例是通過改 變圖片透明度實現輪播,所以所有的圖片位于同一個位置,在默認情況下最后一張圖片會在最上面,第一個圖片是在最下面,而輪播第一張顯示的圖片圖片應該是第 一張,然后是第二張,最后才是第三張,所以要顯示的對每個li設置z—index屬性。并且z-index屬性值依次遞減。我是用js去設置每一個li的 z-index屬性值,但其實并沒有必要這樣做,直接用css屬性就可以了,只不過要寫三個選擇器。
html如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>通過改變透明度實現輪播</title> <link rel="stylesheet" type="text/css" href="index.css" rel="external nofollow" > </head> <body> <div class='warp' id='warp'> <ul class='list' id='list'> <li><img src='img/4274ad202b27b671e622388989399d54.jpg' style='opacity: 1'></li> <li><img src='img/299733ddbe89d6b317cc0e84c43999d4.jpg' style='opacity: 1'></li> <li><img src='img/9b7ec36280e638929aa10ce0955df3d3.jpg' style='opacity: 1'></li> </ul> <div class='pre' id='pre'>《</div> <div class='next' id='next'>》</div> </div> <script type="text/javascript" src='index.js'></script> </body> </html>
css代碼如下
*{ padding: 0; margin: 0; } .warp{ position: relative; width: 100%; } .list{ position: relative; width: 100%; } .list li{ position: absolute; top:0; left: 0; width: 100%; list-style: none; opacity: 1; } li img{ width: 100%; } .pre,.next{ position: absolute; top: 50%; bottom: 0; width: 64px; height: 64px; z-index: 10; margin-top: -32px; text-align: center; line-height: 64px; color: #fff; font-weight: bold; font-size: 30px; cursor: pointer; background-color: transparent; } .pre{ left: 20px; right: auto; } .next{ right:20px; left: auto; } .pre:hover,.next:hover{ background-color: rgba(0,0,0,0.7); }
第二部分(js)涉及的知識有:事件,函數節流,設置定時器,清除定時器
事件由于用的是原生js去實現功能,所以需要考慮瀏覽器兼容問題。
事件流
有 兩種類型的時間流,分別是事件冒泡流和事件捕獲流,這差不多是完全相反的事件流概念,事件冒泡流叫做事件冒泡,這是IE提出的。以一個click事件為 例,在事件冒泡中事件首先發生在最具體的那個元素上,也就是我們單擊的那個元素,然后沿著dom樹向上傳播,在傳播的過程中,每一級節點都會發生 click事件,直到傳播的document對象。事件捕獲流叫做事件捕獲,這是由Netscape Communicator提出的。同樣以一個 click事件為例,在事件捕獲中事件首先發生在最不具體的那個節點上(document對象首先接收到事件),然后沿著dom樹向下傳播,最具體的節點 最后接收到事件,也就是說,實際上被點擊的那個元素最后接收click事件。“DOM2級事件”規定事件流包括三個階段,分別為事件捕獲階段,處于目標階 段和事件冒泡階段。在主流瀏覽器中除了IE不支持DOM事件流,其他瀏覽器都支持DOM事件流。所以IE之支持事件冒泡。但是在將來IE應該會支持DOM 事件流。那時候在綁定事件的時候就不用考慮瀏覽器兼容問題了。目前為了最大程度的兼容各種瀏覽器,我將事件處理程序添加到事件流的冒泡階段。
事件處理程序
》DOM0級事件處理程序
DOM0 級使用為元素的屬性賦值的方式綁定事件,將事件處理程序屬性的值設置為一個函數即可。程序中的this指當前元素。刪除通過DOM0級方法綁定的事件方法 是:將事件處理程序的屬性設置為null。如果一個元素綁定了事件,在把這個元素移除文檔之前,最好手動的的解除這個元素綁定的事件。這樣可以防止元素已 經被移除了但是該元素的事件處理程序的引用還保持在內存中。所以的現代瀏覽器都支持DOM0級事件處理程序。但是用DOM0級綁定事件時,每個元素同一個 事件只能添加一個事件處理程序。
》DOM2級事件處理程序
在“DOM2級事件”中指定事件處理程序的方法為:addEventListener(),第一個參是一個事件名,第二個參數為一個事件處理程序(即一個函 數,可以是匿名函數),第三個參數是一個布爾值。這個布爾值表示在哪一個階段處理事件,當為false時表示在冒泡階段處理,當為true時表示在捕獲階 段處理。為了兼容性我將這個值設置為false。解除用“DOM2級事件”綁定的時間處理程序,需要使用removeEventListener(),匿 名的事件處理程序不能被解除。使用“DOM2級事件”綁定事件時,每個元素同一個事件可以添加多個事件處理程序。用“DOM2級事件”綁架的事件處理程 序,this是指當前元素。
》IE事件處理程序
在IE中指定事件處理程序的方法是 attachEvent(),第一個參數是事件處理程序名(即“on”+事件名),第二個參數是時間處理程序(一個函數,可以是匿名函數)。由于IE只支 持事件冒泡所以事件在冒泡階段處理。使用detachEvent()可以移除用attachEvent()添加的時間處理程序,但是匿名函數不能被移除。 使用attachEvent()綁定事件this指window。。使用attachEvent綁定事件時,每個元素同一個事件可以添加多個事件處理程序。
注:匿名函數不能被移除的原因是:在js中函數是一個對象,這個對象被保存在堆里,函數名是一個指針,指向堆里的對象。對于一個匿名函數而言沒有指針指向它,所以就訪問不到。
事件對象
在兼容DOM的瀏覽器中,事件對象是作為一個參數傳遞到事件處理程序中。(即在兼容DOM的瀏覽器,不論是通過DOM0級或DOM2級綁定事件,都會將事件 對象作為參數傳遞到事件處理程序中),當時IE瀏覽器中,如果用DOM0級指定時間處理程序,事件對象是保存在window的event屬性中,如果用 attachEvent()指定時間處理程序,事件對象是作為一個參數傳遞到事件處理程序中。在兼容DOM的瀏覽器的事件對象中的值和IE的事件對象中的 值存在差異。但它們都有一個共同的值——type(即:被觸發的時間的類型)。在兼容DOM的瀏覽器中,事件對象的target屬性表示事件的目標,以一 個click事件為例,target屬性指最具體的那個元素。在IE瀏覽器中,事件對象的srcElement屬性表示事件目標
在這個案例中,我為最外層的div(它的id為warp)添加了一個click的事件處理程序。通過判斷事件目標的id值確定觸發事件最具體的那個節點。如果事件目 標的id值為pre則切換到上一個圖片,如果事件目標的id值為next則切換到下一張圖片。這兒用的是事件代理,事件代理可以減少使用的內存。
函數節流在這個案例中使用函數節流是為了減少當連續觸發resize事件時瀏覽器的計算量,因為如果瀏覽器的計算量太大,瀏覽器會變慢,甚至崩潰。函數節流的主要思 路是當事件被觸發時,在事件處理程序中,并不是立即做計算,而是使用setTimeout或者setInterval在指定的時間后進行計算。
設置定時器和清除定時器由于要完全講清楚定時器還涉及瀏覽器線程和js的單線程執行等問題現在不做講解。主要是我也還沒有完全的搞明白。在這里提一下瀏覽器是多線程的,開啟定時器 是在瀏覽器的定時器線程,js執行程序是在瀏覽器的另一個線程。瀏覽器除了這兩個線程還沒有其他的線程。等我也明白了瀏覽器線程之間的聯系以后我會再寫一 篇文章。
在這個實例中改變圖片的透明度是通過設置定時器逐漸變大或者逐漸變小。在增加下一張圖片的不透明度之前,要先將當前圖片的不透名都減小到0。
打開頁面自動播放,也是用定時器實現的,如果要停止播放,就清除定時器
js代碼如下
// 當頁面加載完成后將所以需要執行的函數添加到window的load事件上。這兒用的是dom0級事件的綁定,所以不能為window的load事件添加 多個事件處理程序,所以使用的方法是:先判斷window.onload有沒有綁定函數,如果綁定了,就將新的函數追加到尾部,如果沒有綁定,就直接添加 給它。用attachEvent()或者addEventListener()可以為同一個元素的同一個事件綁定多個事件處理程序,可以不用下面這個方法。 function addLoadEvent(func){ var oldLoad = window.onload; if(typeof oldLoad != 'function'){ window.onload = func(); }else{ window.onload = function(){ oldLoad(); func(); } } } //設置class為list的高度,因為圖片的position為absolute所以.list元素的高度為零 //如果一個元素的父元素高度為0,那么設置這個元素的margin: auto 0; 不起作用 function setListHeight(){ var list = document.getElementById('list'); var imgItem = list.getElementsByTagName('img')[0]; var height = imgItem.offsetHeight; var list = document.getElementById('list'); list.style.height = height + 'px'; } //設置li的層級,可以使用css設置 function setLiIndex(){ var list = document.getElementById('list'); var li = list.getElementsByTagName('li'); var liLen = li.length; for(var i = 0;i<liLen;i++){ li[i].style.zIndex = liLen-i; } } var index = 1;//index表示當前顯示的頁面,index是一個全局變量 var timer;// 定時器標識符,如果要清除定時器需要使用它 //事件的跨瀏覽器綁定的對象 var untilEvent = { addEvent:function(element,type,hander){ if(element.addEventListener){ element.addEventListener(type,hander,false); }else if(element.attachEvent){ element.attachEvent('on'+type,hander); }else{ element['on'+type] = hander; } }, getEvent:function(event){ return event?event:window.event; }, getTarget:function(event){ return event.target||event.srcElement; } }; function btnClick(){ var warp = document.getElementById('warp'); untilEvent.addEvent(warp,'click',function(event){ var event = untilEvent.getEvent(event); var target = untilEvent.getTarget(event); switch(target.id){ case 'pre': if(index == 1){//如果當前顯示的圖片已經是第一張圖片,當點擊切換到"上一張"按鈕,則將即將顯示的圖片設置為最后一張圖片 index =3; }else{ --index; } anmitate(); break; case 'next':if(index == 3){//如果當前顯示的圖片已經是最后圖片,當點擊切換到"下一張"按鈕,則將即將顯示的圖片設置為第一張圖片 index = 1; }else{ ++index; } anmitate(); break; } }); } //減小圖片透明度 function decline(cur,inverTime,inverOpacity){ var opacityed = parseFloat(cur.style.opacity); if(opacityed > 0){ cur.style.opacity = opacityed-inverOpacity; setTimeout(function(){ decline(cur,inverTime,inverOpacity); },inverTime); } } //切換圖片的函數 function anmitate(){ var list = document.getElementById('list'); var imgs = list.getElementsByTagName('img'); var imgsLen = imgs.length; var whole = 300;//切換一張圖片用的時間 var inverTime = 5;//時間間隔 var inverOpacity = 1/(whole/inverTime); for(var i = 0;i<imgsLen;i++){ decline(imgs[i],inverTime,inverOpacity); } var go = function(){ var opacityed = parseFloat(imgs[index - 1].style.opacity); if(opacityed < 1){ imgs[index-1].style.opacity = opacityed + inverOpacity; setTimeout(go,inverTime); } }; go(); } //打開頁面自動切換函數 function play() { timer = setTimeout(function () { if(index == 3){ index = 1; }else{ ++index; } anmitate(); play(); // }, 3000); } //停止切換函數,當鼠標移動到輪播上后取消自動切換,當鼠標從輪播上移開,又開始自動切換 function stop() { clearTimeout(timer); } //給最外層div添加鼠標移除和鼠標移入地事件處理程序 function getWarp(){ var warp = document.getElementById('warp'); untilEvent.addEvent(warp,"mouseout",play); untilEvent.addEvent(warp,"mouseover",stop); } //函數節流,當改變窗口大小時,圖片的大小會變化,所以為了讓控制按鈕位于輪播垂直方向的中間,li的高度該隨圖片的大小做變化 function scrollEvent(){ untilEvent.addEvent(window,"resize",function(){ throttle(setListHeight); }); } function throttle(method,context){ clearTimeout(method.Tid); method.Tid = setTimeout(method,70); } addLoadEvent(scrollEvent); addLoadEvent(setListHeight); addLoadEvent(setLiIndex); addLoadEvent(btnClick); addLoadEvent(play); addLoadEvent(getWarp);
感謝各位的閱讀!關于“原生JS如何改變透明度實現輪播效果”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。