05 Flex 實現(xiàn)可伸縮的圖片墻 中文指南

作者:?緝熙Soyaine
簡介:JavaScript30Wes Bos 推出的一個 30 天挑戰(zhàn)财边。項目免費提供了 30 個視頻教程挤庇、30 個挑戰(zhàn)的起始文檔和 30 個挑戰(zhàn)解決方案源代碼。目的是幫助人們用純 JavaScript 來寫東西奥溺,不借助框架和庫,也不使用編譯器和引用。現(xiàn)在你看到的是這系列指南的第 5 篇赠制。完整指南在 GitHub,喜歡請 Star 哦?(?*)

實現(xiàn)效果

可伸縮的圖片墻演示
可伸縮的圖片墻演示

點擊任意一張圖片挟憔,圖片展開钟些,同時從圖片上下兩方分別移入文字。點擊已經(jīng)展開的圖片后绊谭,圖片被壓縮政恍,同時該圖片上下兩端的文字被擠走。若圖片加載不出來达传,請點鏈接看更完整的演示圖片篙耗,在線效果請點這里迫筑。

初始文檔的 DOM 結(jié)構(gòu):以 .panels 為父 div 之下,有 5 個類名為 .paneldiv鹤树,這 5 個各含有 3 個子 p 標(biāo)簽铣焊。而相應(yīng)的 CSS 樣式中,動畫時間等特性已經(jīng)設(shè)定好罕伯,只需要完成不同狀態(tài)下的頁面布局以及事件監(jiān)聽即可曲伊。

涉及特性

  • display: flex
    • flex-direction
    • justify-content
    • align-items
  • transform: translateX/translateY
  • element.classList.toggle()
  • transitionend 事件

過程指南

CSS 部分

CSS 在這個過程中占了重點,運用 flex 可以使各個元素按一定比例占據(jù)頁面追他。在調(diào)試的時候坟募,可以把邊框顯示出來方便查看效果。(border: 1px solid #f00;

  1. .panels 設(shè)置為 display:flex
  2. 設(shè)定每個子 panel 的 flex 值為 1
  3. 針對每個子 panel邑狸,設(shè)為 display:flex懈糯,設(shè)置其 flex 主軸方向
  4. 控制 .panle 的子元素 <p> 中的文字垂直、水平居中(單獨看每個 panel单雾,其中的文字也可以用 flex 的思路來使其三等分后居中)
    1. 設(shè)置為 display:flex
    2. 設(shè)置 flex
    3. 設(shè)置其子元素的布局方式:垂直水平居中(沿主軸赚哗、側(cè)軸居中)
  5. 設(shè)定點擊圖片后文字移動的樣式
  6. 設(shè)定點擊圖片展開后的圖片的 flex

JS 部分

  1. 獲取所有類名為 panel 的元素
  2. 為其添加 click 事件監(jiān)聽,編寫觸發(fā)事件調(diào)用的函數(shù)(給觸發(fā)的 DOM 元素添加/去掉樣式硅堆,實現(xiàn)拉伸/壓縮的效果)
  3. 為其添加 transitionend 事件監(jiān)聽屿储,編寫調(diào)用的函數(shù)(添加/去掉樣式,實現(xiàn)文字的飛入/飛出效果)

相關(guān)知識

Flexbox

MDN flexbox 圖示
MDN flexbox 圖示

這一個挑戰(zhàn)的關(guān)鍵部分就在于理解如何使用 Flexbox渐逃,挑戰(zhàn)的文檔里嵌套了三個 flex 容器够掠,作為彈性盒子,它們各自的作用是:

  • .panels:使其中的 .panel 按橫向的 flex 等分排布(此處為五等分)
  • .panel:使其中的 <p> 按縱向的 flex 等分排布(此處為三等分)
  • p :借用 flex 相對于主軸及側(cè)軸的對齊方式茄菊,使其中的文字垂直水平居中

這里容易混淆的是不同 CSS 屬性的應(yīng)用對象疯潭,想?yún)^(qū)分很簡單,只需記住針對容器內(nèi)子元素的特性較少(只有 5 個)面殖,可以這樣聯(lián)想:針對某一個具體的小元素進行設(shè)置竖哩,可供發(fā)揮的空間比較少,而針對 Flex 容器本身脊僚,有統(tǒng)籌大局的責(zé)任期丰,故特性多一些。下面簡單介紹一些基本的特性(沒有完全列出)吃挑。

針對 Flex items 的特性(Children)

  • flex-growth:伸展值
  • flex-shrink:可接受的壓縮值
  • flex-basis:元素默認的尺寸值
  • flex:以上三個值按順序的縮寫

針對 Flex container 的特性(Parent)

  • display: flex:將這個元素設(shè)置成彈性盒子
  • flex-direction:主軸方向
    • row:橫向
    • column:縱向
  • justify-content:沿主軸的的對齊方式
  • align-items:沿側(cè)軸的對齊方式
  • align-content:子元素中文本沿側(cè)軸的對齊方式(只有一行時無效)

可以在下面幾個地方試一下 Flex 的各種特性:

延伸思考

在 index-FINISHED.html 的解決方案中,用了兩種 class 值來分別控制 div 元素和 p 元素的動畫街立,這就會造成一個問題舶衬,當(dāng)快速點擊兩下時,會出現(xiàn)相反的組合(圖片縮小 + 上下文字出現(xiàn))赎离。

那為什么還要將文字的移動動畫用 .open-actived 這個類來控制逛犹,同時還多加上了一個 transitionend 的事件監(jiān)聽,而不是直接用 .open 控制文字的移動,并且只采用一個 click 事件監(jiān)聽呢虽画?

我試了一下舞蔽,發(fā)現(xiàn)如果將要觸發(fā)的文字移動(transform)用 .open 來控制,那么會出現(xiàn)有點不協(xié)調(diào)的狀況码撰。

要找到問題所在渗柿,可以先研究一下動畫效果,由于錄 GIF 很容易掉幀脖岛,最好打開網(wǎng)頁來看細節(jié)朵栖。

當(dāng)拉伸圖片時,首先往里壓縮(階段①)柴梆,然后再展開(階段②)陨溅,而文字是階段②出現(xiàn)的;而當(dāng)壓縮圖片時绍在,也是同樣的道理门扇,先微微拉開一點(階段①),然后再往里縮(階段②)偿渡,文字也是在階段②才往上移動的臼寄,這樣就形成了一種被 pia 飛的效果。

這樣也就可以回答我最開始的疑問卸察,為何要多添加一個 transitioned 的事件監(jiān)聽脯厨,這個事件會在 transition 結(jié)束之后被觸發(fā),所以目的是先讓圖片的壓縮拉伸完成坑质,再移動文字合武。

也就是說,如果除去字體大小的變化涡扼,具體的動畫細節(jié)其實是這樣的:

  • 圖片展開:微微壓縮一段距離 -> 展開圖片 -> 文字向中心移動
  • 圖片壓縮:微微展開一段距離 -> 壓縮圖片 -> 文字向上下移動

這就解釋了為什么我改動之后出現(xiàn)了不協(xié)調(diào)稼跳,此時看到的動畫,像是文字主導(dǎo)了圖片的壓縮伸展吃沪,原因就是文字動畫的時機不太對汤善,找到了這個原因,就很好解決了票彪。(見 index-SOYAINE2.html

.panel > * {
    /* ... */
    transition:transform 0.5s 0.7s;
}

/* 修改 .open-actived -> .open*/
.panel.open p:first-child {
    transform: translateY(0);
}

.panel.open p:last-child {
    transform: translateY(0);
}
const panels = document.querySelectorAll('.panel');

function toggleOpen(e) {
    this.classList.toggle('open');
}

panels.forEach( panel => panel.addEventListener('click', toggleOpen, false));
// 去掉對于 transitionend 的事件監(jiān)聽

解決思路是讓 p 標(biāo)簽的文字動畫效果延遲一下红淡,添加 transition 屬性的 delay 值,使其到圖片變換的階段②再發(fā)生降铸,此處我選用了圖片的動畫最長時間 0.7s在旱,圓滿解決。

挑戰(zhàn) 5 Pass (≧▽≦)/

05
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末推掸,一起剝皮案震驚了整個濱河市桶蝎,隨后出現(xiàn)的幾起案子驻仅,更是在濱河造成了極大的恐慌,老刑警劉巖登渣,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件噪服,死亡現(xiàn)場離奇詭異,居然都是意外死亡胜茧,警方通過查閱死者的電腦和手機粘优,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竹揍,“玉大人敬飒,你說我怎么就攤上這事》椅唬” “怎么了无拗?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昧碉。 經(jīng)常有香客問我英染,道長,這世上最難降的妖魔是什么被饿? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任四康,我火速辦了婚禮,結(jié)果婚禮上狭握,老公的妹妹穿的比我還像新娘闪金。我一直安慰自己,他們只是感情好论颅,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布哎垦。 她就那樣靜靜地躺著,像睡著了一般恃疯。 火紅的嫁衣襯著肌膚如雪漏设。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天今妄,我揣著相機與錄音郑口,去河邊找鬼。 笑死盾鳞,一個胖子當(dāng)著我的面吹牛犬性,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播腾仅,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼仔夺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了攒砖?” 一聲冷哼從身側(cè)響起缸兔,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吹艇,沒想到半個月后惰蜜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡受神,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年抛猖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鼻听。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡财著,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出撑碴,到底是詐尸還是另有隱情撑教,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布醉拓,位于F島的核電站伟姐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亿卤。R本人自食惡果不足惜愤兵,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望排吴。 院中可真熱鬧秆乳,春花似錦、人聲如沸钻哩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽憋槐。三九已至双藕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阳仔,已是汗流浹背忧陪。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留近范,地道東北人嘶摊。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像评矩,于是被迫代替她去往敵國和親叶堆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 選擇qi:是表達式 標(biāo)簽選擇器 類選擇器 屬性選擇器 繼承屬性: color斥杜,font虱颗,text-align沥匈,li...
    wzhiq896閱讀 1,731評論 0 2
  • 選擇qi:是表達式 標(biāo)簽選擇器 類選擇器 屬性選擇器 繼承屬性: color,font忘渔,text-align高帖,li...
    love2013閱讀 2,303評論 0 11
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評論 25 707
  • 看到這個題目肮韧,你是否會覺得應(yīng)該是一個在情場上摸爬滾打過的人寫的止剖?很遺憾地告訴你寡键,我只是一個談過2段戀愛沽一,并且兩次加...
    錢老師碎碎念閱讀 380評論 0 2
  • Velocity:基于Java的模板引擎滔驶,可以用Java代碼渲染的簡單而又強大的模板語言生真。開發(fā)Web時儒将,可以將We...
    欒呱呱閱讀 2,202評論 0 1