JavaScript30 爲Wes Bos推出的一項爲期30天的挑戰,旨在幫助人們用純JavaScript來實現效果,初學者若想在JS方面快速精進,不妨一試。本題爲第五題。javascript
點擊任意一張圖片,圖片放大X倍,同時圖片上下兩方飛入文字,再點擊已經展開的圖片後,圖片被壓縮,同時頂端和底部的文字飛出。查看個人代碼和demo。 css
觀察文檔初始佈局:在類名爲.panels
的父元素div
之下,有5個類名爲.panel
的子div
,這5個div
內均包含3個p
標籤。文檔內也已提供CSS
樣式及動畫,作題者只需稍許補充並添加監聽事件便可。html
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
......
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
複製代碼
在本章中,大量運用flex
佈局知識,如需補課,推薦查閱阮一峯大神的博客:java
.panels
爲display:flex
,默認項目沿主軸方向,從左到右排列;.panel
爲display:flex
,並設置屬性:
flex: 1
,flex
爲flex-grow
, flex-shrink
和flex-basis
的簡寫;justify-content: center
,該屬性規定項目在主軸上的對齊方式,center
即沿主軸居中排列。flex-direction: column
,該屬性定義主軸的方向(即項目的排列方向),column
表示主軸爲垂直方向,起點在上沿;align-items: center
,即項目在交叉軸上居中對齊。flex
值。.panel
的元素;click
監聽事件,觸發調用函數,添加或去除樣式,實現圖片拉伸或壓縮的效果;transitionend
監聽事件,觸發調用函數,添加或去除樣式,實現頂端及底部文字飛入或飛出效果。html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh;
overflow: hidden;/*內容溢出元素框時,內容會被修剪,而且其他內容不可見 */
display: flex;
}
.panel {
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255, 255, 255, 0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition: font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11),
flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
flex: 1;
justify-content: center;
display: flex;
flex-direction: column;
}
.panel1 {background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);}
......
.panel5 {background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
}
/* Flex Items */
.panel>* {
margin: 0;
width: 100%;
transition: transform 0.5s;
flex: 1 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.panel>*:first-child {
transform: translateY(-100%);
}
.panel.open-active>*:first-child {
transform: translateY(0);
}
.panel>*:last-child {
transform: translateY(100%);
}
.panel.open-active>*:last-child {
transform: translateY(0);
}
.panel p {
text-transform: uppercase;
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
flex: 5;
font-size: 40px;
}
複製代碼
const Panels = document.querySelectorAll('.panel');
function clearOpen() {
Panels.forEach(panel => panel.classList.remove('open'))
}
function toggelOpen() {
this.classList.toggle('open');
}
function toggleActive(e) {
if (e.propertyName.includes('flex')) {
this.classList.toggle('open-active')
}
}
Panels.forEach(panel => panel.addEventListener('click', toggelOpen));
Panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
複製代碼
採用 Flex 佈局的元素,稱爲 Flex 容器。它的全部子元素自動成爲容器成員,稱爲 Flex 項目。容器默認存在兩根軸:水平的主軸main axis
和垂直的交叉軸cross axis
。 git
flex-direction
屬性決定主軸的方向(即項目的排列方向);flex-wrap
屬性定義,若是一條軸線排不下,如何換行;flex-flow
屬性是flex-direction
屬性和flex-wrap
屬性的簡寫形式;justify-content
屬性定義了項目在主軸上的對齊方式。align-items
屬性定義項目在交叉軸上如何對齊。align-content
屬性定義了多根軸線的對齊方式。若是項目只有一根軸線,該屬性不起做用。order
屬性定義項目的排列順序。數值越小,排列越靠前,默認爲0。flex-grow
屬性定義項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大。flex-shrink
屬性定義了項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小。flex-basis
屬性定義了在分配多餘空間以前,項目佔據的主軸空間。flex
屬性是flex-grow
, flex-shrink
和 flex-basis
的簡寫,默認值爲0 1 auto
。align-self
屬性容許單個項目有與其餘項目不同的對齊方式,可覆蓋align-items
屬性。.panels
:使得子元素.panel
橫向等分排列;.panel
:使得其中的<p>
縱向等分排列;p
:使得其中的文字垂直水平居中分佈。 不過以上對Flex的介紹還不算詳細,若想深刻了解,可查閱這裏。爲實現頂端及底部文字飛入飛出的效果,題中使用了一個用法,即transform: translateY,可實現元素在Y軸方向上移動。github