|
發(fā)現(xiàn):display動(dòng)畫的應(yīng)用 整件事的起因是什么呢?在筆者最近為社團(tuán)計(jì)劃的官網(wǎng)上打算做一個(gè)這樣的效果:點(diǎn)擊頭像,左邊/右邊滑出一個(gè)“面板”,里面展示用戶的個(gè)人信息。 當(dāng)然,這有很多種做法,比如:利用position定位+overflow溢出隱藏、利用opacity/visibility隱藏+pointer-events元素穿透… 但是筆者當(dāng)時(shí)想到的是如何給”真正的隱藏,display“加上動(dòng)畫! 我們大概都知道的是:HTML渲染過程中有一個(gè)可能執(zhí)行的、影響頁面性能的“回流”和“重繪”的過程。導(dǎo)致這個(gè)過程被觸發(fā)的原因有很多:元素位置移動(dòng)、大小改變、增刪節(jié)點(diǎn)以及這里要說的display顯示與隱藏切換等等。而元素的變動(dòng)需要頁面快速的顯示出來,所以在我們看來是“突?!钡?。 /** css代碼 */width: 50px;height: 50px;background-color: red;display: none;transform: translateX(0);transition: all .6s ease; //似乎沒用? //js代碼 ds.style.display="block"; ds.style.transform="translateX(100px)"; 但是同樣的,當(dāng)對(duì)以下屬性進(jìn)行操作的時(shí)候,由于瀏覽器的渲染機(jī)制有一些API可以使頁面強(qiáng)制渲染(因?yàn)橐@得詳細(xì)確切的信息),包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。這會(huì)直接導(dǎo)致前后兩行相當(dāng)于“渲染了兩遍”。 所以將上方js代碼改為下面這樣: //js代碼 ds.style.display="block"; ds.offsetHeight; ds.style.transform="translateX(100px)"; 目前csdn官網(wǎng)PC端blink發(fā)布頁面的圖片上傳就用了類似這個(gè)功能! 后來還是覺得這種方式需要涉及js對(duì)頁面結(jié)構(gòu)的改變,于是乎… 實(shí)現(xiàn):如何實(shí)現(xiàn)文首展示的效果 這基于position定位是會(huì)“重合”的:在兩個(gè)行內(nèi)元素都設(shè)置了定位屬性(但沒有加top/left/bottom/right定位)后,后面的會(huì)覆蓋前面的;這時(shí)候可以通過margin移動(dòng)位置展示。 只能是行內(nèi)元素,行內(nèi)塊元素都不行。 ——云小夢 它大概結(jié)構(gòu)是這樣的: <div> <div> <!-- 這里放右側(cè)彈框展示的信息 --> </div> <div> <!-- "頁面"的遮罩層 --> <div></div> <!-- 這里放“頁面”數(shù)據(jù)結(jié)構(gòu)(也就是原本應(yīng)該在body標(biāo)簽下的所有東西) --> </div> <!-- 這是占位元素 --> <div></div></div> 實(shí)際就像這樣的: <div> <div>哈哈哈</div> <div> <div></div> <div id="boxs"> <div style="background-color:#ffc5c5;"></div> <div style="background-color:#7171f7;"> flex下兩列布局左邊固定右邊寬高自適應(yīng) </div> </div> <div></div> <a href="#">千萬小心像對(duì)a設(shè)置全局樣式(這叫啥樣式重置)</a> <div> <div></div> <button>到指定地點(diǎn)</button> </div> <form id="form" action="#"> <input type="submit" value="="踢腳板 /> </form> <img id="img" src="compress/compress/img/mxc_16x16.png" /> </div> <div></div></div> 如上,class為“box”的div里面放的就是“原本的頁面整體”部分。為了達(dá)到想要的效果,我們采用了flex布局! flex簡寫時(shí)包括三個(gè)屬性:flex-grow、flex-shrink和flex-basis —— flex-grow:指定了容器剩余空間多余時(shí)候的分配規(guī)則,默認(rèn)值是0,多余空間不分配; flex-shrink:指定了容器剩余空間不足時(shí)候的分配規(guī)則,默認(rèn)值是1,空間不足要分配; flex-basis:flex-basis則是指定了固定的分配數(shù)量,默認(rèn)值是auto。設(shè)置的同時(shí)需設(shè)置width或者h(yuǎn)eight屬性; /* 列表僅水平滾動(dòng) */.page_list { width: 100vw; display: flex; overflow-y: hidden; }/* 主內(nèi)容寬度100%,白色背景覆蓋 */.box { flex: 0 0 100vw; height: 100%; background-color: #fff; position: relative; overflow-y: auto;overflow-x: hidden;transition: all .6s ease; }/** 遮罩層樣式 */.zb_mask{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 100; background-color: rgba(0,0,0,.2); pointer-events: none; opacity: 0; transition: all .6s ease;}/* 空標(biāo)簽元素,作用是騰出水平滾動(dòng)空間 */.space { flex: 0 0 12rem; }/* 按鈕固定定位,藏在內(nèi)容白色背景后面 */.z_two_page { width: 12rem; position: fixed; right: 0; top: 0; } 大概就是:什么也不干的情況下只展示box的內(nèi)容(也就是和不加這些花里胡哨的div一樣的效果),它是用background覆蓋后面的class為“space”的占位元素;在”哈哈哈“展示的時(shí)候,box右移。 這里需要注意的是:為什么“哈哈哈”所屬div在前而“頁面”所屬div在后? 代碼中flex的前兩個(gè)屬性值為0,表示在空間增大或縮小時(shí)依然保持原狀(這是本文的基礎(chǔ)?。?,第三個(gè)元素則寫了展示時(shí)的“默認(rèn)大小”:如你所看,box承載的是頁面,所以它是100vw,而class為“z_two_page”的元素這里設(shè)置了12rem ,你完全可以將這個(gè)值換掉! 那如何將“哈哈哈”展示在視野中? —— js控制“代表頁面的元素”整體移動(dòng)即可。 這里有個(gè)“遮罩層效果”,按照傳統(tǒng)的js實(shí)現(xiàn)肯定就要去找display了,再進(jìn)一步可以用上面所說的“display動(dòng)畫效果”增強(qiáng)體驗(yàn)。 let right=document.querySelector(".right");let box=document.querySelector(".box");let mask=document.querySelector(".zb_mask"); right.onclick=function(){ box.style.marginLeft="-12rem"; mask.style.cssText+="opacity: 1;pointer-events: all;"} mask.onclick=function(){ box.style.marginLeft="0"; mask.style.cssText+="opacity: 0;pointer-events: none;"} 最后,考慮到移動(dòng)端頁面展示的一些問題,比如:右側(cè)留白問題、原生手勢對(duì)頁面整體的影響等,我們一般會(huì)在css中設(shè)置 html{max-width: 100vw;overflow-x: hidden;} 。如果你想要用戶在移動(dòng)端依然只能夠通過點(diǎn)擊彈出側(cè)邊欄,在這里我們可以在css中加上限制 —— 設(shè)置上方功能只有在PC端生效: @media (any-hover: none) { .page_list{ overflow-x: hidden; } |
|
|