您好,登錄后才能下訂單哦!
利用JavaScript怎么實現(xiàn)一個瀑布流效果?相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
JavaScript是一種直譯式的腳本語言,其解釋器被稱為JavaScript引擎,是瀏覽器的一部分,JavaScript是被廣泛用于客戶端的腳本語言,最早是在HTML網(wǎng)頁上使用,用來給HTML網(wǎng)頁增加動態(tài)功能。
<div id="main">//一個main包含了整個頁面內(nèi)容,box用來做一個外容器,img作為圖片容器 <div class="box"> <div class="pic"> <img src="img/0.jpg"> </div> </div> <div class="box"> <div class="pic"> <img src="img/0.jpg"> </div> </div> <div>
//CSS //這里面的填充用padding值,因為offsetHeight是包括一個padding而不包括margin的方便以后高度的測量 *{ margin: 0px; padding: 0px; } #main{ position: relative;//在main上設(shè)置相對定位,在JS給box設(shè)置絕對定位,來控制圖片位置 } .box{ padding: 15px 0 0 15px; float: left; } .pic{ padding: 10px; border: 1px solid #ccc; border-radius:5px; box-shadow: 0 0 5px #ccc; } .pic img{ width: 168px;//瀑布流統(tǒng)一寬度但不同一高度,高度為自適應(yīng)就好 height: auto; }
JS代碼
在我們寫JS代碼之前,我們需要搞明白我們需要什么方法,是否需要封裝起來調(diào)用,我們第一步要干什么,
那么我們第一步要干什么呢?我們做瀑布流首先要做的是獲取到所有小部件也就是box,我們無論做什么處理都是對box的處理或者img的處理,所以要獲取到所有的box,所以我們可以把它封裝起來
//根據(jù)class獲取元素 function getByClass(parent,clsName){//傳入父元素和想要的class var boxArr=new Array//用來存儲獲取到所有class為box的元素,可以用對象的方式也可以用[]創(chuàng)建 oElements=parent.getElementsByTagName('*');//取出所有子元素 for (var i = 0; i < oElements.length; i++) {//我們需要遍歷所有的子元素 if(oElements[i].className==clsName)//如果我們找到了相應(yīng)的子元素 boxArr.push(oElements[i]);//取出傳過來相等的className //push是數(shù)組自帶的方法 }; return boxArr;返回數(shù)組 }
這樣我們就得到了我們想要的class,之后該怎么辦呢,先從一個box下手,我們需要取得第一排到底有多少個元素,因為之前我們并沒有確定我們main的寬度,所以是自適應(yīng)的也就是說我們把頁面縮小,我們每一排的元素也會相應(yīng)的減少,為了能讓瀑布流的代碼有更好的應(yīng)用性,讓不同尺寸的圖片都可以應(yīng)用,所以,我們需要手動計算一排究竟可以放多少張圖片呢,那如何計算呢?
我們可以算出頁面總寬在box的寬,就OK了
var oBoxW=oBoxs[0].offsetWidth;//box的寬,提到了里面計算了padding的值
var clos=Math.floor(document.documentElement.clientWidth/oBoxW)//求列數(shù)
這樣我們就求出了列數(shù),無論圖片的寬度如何變,我們都可以算出來
floor是用來取整數(shù)的,因為我們的px是沒有浮點(diǎn)數(shù)類型的避免計算錯誤,所以取整
oparent.style.cssText='width:'+oBoxW*clos+'px; margin :0 auto';
設(shè)置main的寬度
我們已經(jīng)取得了列數(shù)之后呢我們第一排的圖片肯定是一排寬度相等,長度不一是吧,也就是說,我們第二排的圖片需要接上第一排圖片的后邊,我們不能一排一排操作,但我們可以一個一個操作,怎么操作呢,我們可以取到第一排高度最小的將下一張圖片,也就是如果第一排7個,那下一個就是第八個,把第八個圖片放在最小高度的圖片上,如何實現(xiàn)呢,我們先試想一下,我們首先需要求出第一排中最小,我們有一個Math.min求最小,但是呢我們這個函數(shù)無法傳入用數(shù)組,只能是具體的數(shù)怎么半呢,apply來擴(kuò)展作用域
用代碼展示下
var hArr=[];//每一列高度的值 for (var i = 0; i < oBoxs.length; i++) { if(i<clos){//先記錄好第一排高度 hArr.push(oBoxs[i].offsetHeight);//放進(jìn)去 }else{//如果到達(dá)第二排,就開始計算 var minH=Math.min.apply(Math,hArr);最小值計算 //為什么可以呢,本來不能傳數(shù)組,我們通過apply綁定作用域在Math上,也就是說還是執(zhí)行這個函數(shù)但是,apply第二個參數(shù)需要是數(shù)組,所以間接地把參數(shù)變成了數(shù)組傳進(jìn)去,也就是說我們還是用了Math函數(shù)但值變成了數(shù)組里的值。 //console.log(minH) var index=getMinhIndex(hArr,minH)//獲取索引 oBoxs[i].style.position="absolute";我們就可以找到,傳入數(shù)組和最小值 oBoxs[i].style.top=minH+"px";那下一張圖片的高度救球出來了 oBoxs[i].style.left=oBoxW*index+"px";左邊的距離就是索引乘以元素的寬 hArr[index]+=oBoxs[i].offsetHeight;//我們添加了一個圖片后需要刷新數(shù)組里的高度,再去尋找下一個最小的,再向他的下面添加圖片,一次循環(huán) } }; function getMinhIndex (arr,val){ for(var i in arr){//在其中找到最小值,返回索引 if(arr[i]==val){ return i; } } }
以上就大體做出了一個瀑布流的樣式,就差拖動滾動條加載了,這里面肯定需要后臺的支持,在慕課上,老師做了一個偽處理,這里建議看慕課視頻,有圖解十分清楚,我用語言或圖片不太好表達(dá)
var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'}]}//我們自己寫一個json數(shù)據(jù) window.onscroll=function(){ if(checkScrollSlide){ var oparent=document.getElementById("main") //將數(shù)據(jù)快渲染到當(dāng)前頁面尾部 for (var i = 0; i < dataInt.data.length; i++) {//添加 var oBox=document.createElement("div"); oBox.className="box"; oparent.appendChild(oBox); var opic=document.createElement('div'); opic.className='pic'; oBox.appendChild(opic); var oimg=document.createElement('img'); oimg.src='img/'+dataInt.data[i].src;//將數(shù)據(jù)加進(jìn)去 opic.appendChild(oimg) } waterfall('main','box');//一會看完整代碼,這就是剛才那些的封裝 } } function checkScrollSlide(){//檢測是否具備加載數(shù)據(jù)塊的條件 var oparent=document.getElementById('main'); var oBoxs=getByClass(oparent,'box') var lastBoxH=oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2)求出最后一個圖片的一半距離頁面頂端的距離 var scrollTop=document.body.scrollTop||document.documentElement.scrollTop; var height=document.body.clientHeight||document.documentElement.clientHeight; return(lastBoxH<scrollTop+height)?true:false;//如果頁面距離頂部(包括滾輪)的距離比滾輪加頁面距離小,那么就返回true }
完整JS代碼
window.onload=function(){ waterfall('main','box'); //json var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'}]} window.onscroll=function(){ if(checkScrollSlide){ var oparent=document.getElementById("main") //將數(shù)據(jù)快渲染到當(dāng)前頁面尾部 for (var i = 0; i < dataInt.data.length; i++) { var oBox=document.createElement("div"); oBox.className="box"; oparent.appendChild(oBox); var opic=document.createElement('div'); opic.className='pic'; oBox.appendChild(opic); var oimg=document.createElement('img'); oimg.src='img/'+dataInt.data[i].src; opic.appendChild(oimg) } waterfall('main','box'); } } } function waterfall(parent,box){ //將main下所有class為box的元素取出來 var oparent=document.getElementById(parent); var oBoxs=getByClass(oparent,box) //console.log(oBox.length) //計算整個頁面的列數(shù)(頁面寬/box寬) var oBoxW=oBoxs[0].offsetWidth; //console.log(oBoxW); var clos=Math.floor(document.documentElement.clientWidth/oBoxW)//求列數(shù) //console.log(clos) //設(shè)置main的寬 oparent.style.cssText='width:'+oBoxW*clos+'px; margin :0 auto'; var hArr=[];//每一列高度的值 for (var i = 0; i < oBoxs.length; i++) { if(i<clos){ hArr.push(oBoxs[i].offsetHeight); }else{ var minH=Math.min.apply(Math,hArr); //console.log(minH) var index=getMinhIndex(hArr,minH)//索引 oBoxs[i].style.position="absolute"; oBoxs[i].style.top=minH+"px"; oBoxs[i].style.left=oBoxW*index+"px"; hArr[index]+=oBoxs[i].offsetHeight;//更改數(shù)組 } }; //console.log(hArr) } //根據(jù)class獲取元素 function getByClass(parent,clsName){ var boxArr=new Array//用來存儲獲取到所有class為box的元素 oElements=parent.getElementsByTagName('*');//取出所有子元素 for (var i = 0; i < oElements.length; i++) { if(oElements[i].className==clsName) boxArr.push(oElements[i]);//取出傳過來相等的className }; return boxArr; } function getMinhIndex (arr,val){ for(var i in arr){ if(arr[i]==val){ return i; } } } function checkScrollSlide(){//檢測是否具備加載數(shù)據(jù)塊的條件 var oparent=document.getElementById('main'); var oBoxs=getByClass(oparent,'box') var lastBoxH=oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2) var scrollTop=document.body.scrollTop||document.documentElement.scrollTop; var height=document.body.clientHeight||document.documentElement.clientHeight; return(lastBoxH<scrollTop+height)?true:false; }
看完上述內(nèi)容,你們掌握利用JavaScript怎么實現(xiàn)一個瀑布流效果的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。