JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用课程,课程主打 No Frameworks
、No Compilers
、No Libraries
、No Boilerplate
在30天的30部教学影片里,建立30个JavaScript的有趣小东西。
另外,Wes Bos 也很无私地在 Github 上公开了所有 JS 30 课程的程序码,有兴趣的话可以去 fork 或下载。
利用 flexbox
、transition
等 CSS 属性,搭配 JS 监听 transitionend
、click
事件,最终实作出一个美观的 Image Gallery。
由最外层的.panels
包覆住内部的5个.panel
所形成的一个巢状结构。
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
(仅说明影片中更动的部分)
先将最外层的 .panels
显示类型设定为 flex
,它同时也作为一个 flex-container
包覆住内部的五个 flex-items
也就是 .panel
。
.panels {
/*其余略过*/
display: flex;
}
flex
是 flex-grow
、flex-shrink
、flex-basis
的简写,只有指定一个值给 flex
时,则代表设定的是 flex-grow
,其余属性以预设值带入。
flex-grow
可以指定 flex-container
的剩余空间该如何分配,下面所有的 .panel
的 flex-grow
都是 1,也就是均匀分配剩余空间。
接着,将每一个 .panel
的显示类型都设定为 flex
(此时的.panel
对下面的<p></p>
来说就是 flex-container
) 并将其下的 flex-item
在水平、铅直方向都置中。
最後,设定 flex-direction
将 flex-box
的 main-axis
更改为直列。
.panel {
flex: 1; /*将每个 flex-item 的大小都设为一样并填满*/
display: flex;
justify-content: center; /*在水平方向置中*/
align-items: center;/*在铅直方向置中*/
flex-direction: column;
}
将 .panel
(flex-container
)下的 <p></p>
(flex-item
) 的 flex
属性设定为 1、0、auto,也就是均匀分配 flex-container
的剩余空间、flex-item
长度超过 flex-container
时的收缩量设为 0、flex-item
在 flex container
的初始大小设为自动(auto)。
接着,也将<p></p>
当作是一个 flex-container
,设定显示类型为 flex
。透过 justify-content
、align-items
,将标签内的文字(flex-item
) 水平、铅直置中排列。
.panel > * {
/*其余省略*/
flex: 1 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
初始状态,分别将在 .panel
上方和下方的 <p></p>
都各上移、下移 100% 以达到隐藏的效果。
.panel > *:first-child{
transform: translateY(-100%);/*上移*/
}
.panel > *:last-child{
transform: translateY(100%);/*下移*/
}
接着设定当.panel
上有open-active
这个 class 时,就将原本隐藏的文字分别下移和上移显示出来。
.panel.open-active > *:first-child{
transform: translateY(0);
}
.panel.open-active > *:last-child{
transform: translateY(0);
}
.panel
开启时,将内部文字放大为 40px 并将 flex-container
剩余分配的位置变为原来的5倍。
.panel.open {
font-size: 40px;
flex: 5;
}
CSS flex 属性
图解 Flexbox 基本属性
FLEXBOX FROGGY-学习 flexbox 的小游戏
取得所有的.panel
并放到 NodeList
'panels'
中。
const panels = document.querySelectorAll('.panel');
为 panels
中的每一个.panel
都注册两个事件监听器,当 click
或 transitionend
事件发生时,就分别以 toggleOpen
和 toggleActive
方法进行事件处理。
panels.forEach(panel => panel.addEventListener('click',toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend',toggleActive));
点击任意一个.panel
,toggleOpen()
方法会替触发事件的.panel
依照情况的不同,新增或是移除.open
这个 class,若是触发事件的.panel
原本没有.open
则新增,有的话则移除.open
。
当 transitionend
事件发生,toggleActive()
会作出如同 toggleOpen()
一样的判断,决定新增还是移除.open-active
这个 class。因为同时会被触发的 transitionend
事件有很多个,我们决定在触发 transitionend
事件的 CSS 属性是 flex
时,才采取处理。为什麽不写 e.propertyName == 'flex-grow'
是因为在 Safari 显示的是 flex
而 Chrome、FireFox 显示的是 flex-grow
,为避免这个差异导致错误,我们可以使用 include('flex'),当 propertyName 含有 flex
就进行事件处理。
function toggleOpen(){
this.classList.toggle('open');
}
function toggleActive(e){
if(e.propertyName.includes('flex')){
this.classList.toggle('open-active');
}
}
Element.classList
String.prototype.includes()
好的!【足以维护资讯系统的人才】已经到位啦! 所以就就可以针对资讯资产来做管理! A.8 资产管理 ...
今天要接续昨天的排程备份来实作「异地备份」 读者们如果对rsync操作尚不熟悉,可到 昨天 复习喔 ...
ProduKey 既然 Forensics 分类的工具都看完了,接下来看看 System Tools...
今天来为大家介绍资料储存容器的练习题, 过程跟解法可能跟大家不太一样还请大家见谅, 那就让我们开始吧...
Mac ARM 作为主要开发机是否可行? 对我来说,完全可以,我有在撰写的语言为 C#, JS, J...