摘要:本項(xiàng)目將制作一個(gè)交互動(dòng)畫(huà)效果,令其在單詞原詞和數(shù)略詞之間切換。二擴(kuò)展應(yīng)用到多個(gè)單詞數(shù)略詞有很多,為了能夠一次展示多個(gè)單詞,我們將對(duì)現(xiàn)有的程序進(jìn)行擴(kuò)展。
效果預(yù)覽
按下右側(cè)的“點(diǎn)擊預(yù)覽”按鈕可以在當(dāng)前頁(yè)面預(yù)覽,點(diǎn)擊鏈接可以全屏預(yù)覽。
https://codepen.io/comehope/pen/byvRxB
可交互視頻此視頻是可以交互的,你可以隨時(shí)暫停視頻,編輯視頻中的代碼。
請(qǐng)用 chrome, safari, edge 打開(kāi)觀看。
視頻1: https://scrimba.com/p/pEgDAM/cR4gpGsa
視頻2: https://scrimba.com/p/pEgDAM/czNp3MUZ
每日前端實(shí)戰(zhàn)系列的全部源代碼請(qǐng)從 github 下載:
https://github.com/comehope/front-end-daily-challenges
代碼解讀大家是否見(jiàn)過(guò) “i18n”、“a11y” 這樣的英文單詞?它們其實(shí)是一些單詞的縮寫(xiě),“i18n” 代表的是 “internationalization”(國(guó)際化),“a11y” 代表的是 “accessibility”(可訪問(wèn)性),因?yàn)榘淖帜柑嗔耍钥s寫(xiě)時(shí)只保留頭尾的字母,再把余下的字符個(gè)數(shù)寫(xiě)在中間,這種寫(xiě)法稱為“Numeronym”,我把它翻譯成“數(shù)略詞”。據(jù)說(shuō)最長(zhǎng)的單詞是 “pneumonoultramicroscopicsilicovolcanoconiosis”,由 45 個(gè)字母組成,意思是一種肺部疾病。
本項(xiàng)目將制作一個(gè)交互動(dòng)畫(huà)效果,令其在單詞原詞和“數(shù)略詞”之間切換。整個(gè)項(xiàng)目分成二個(gè)步驟開(kāi)發(fā),第一步先實(shí)現(xiàn)一個(gè)固定單詞的交互動(dòng)畫(huà),第二步改寫(xiě)為能自動(dòng)處理任意的單詞,然后擴(kuò)展應(yīng)用到多個(gè)單詞上。
一、一個(gè)固定單詞的交互動(dòng)畫(huà)dom 結(jié)構(gòu)如下,最外側(cè)的容器名為 .container,其中包含一個(gè)名為 .word 的 元素,分別代表單詞的第1個(gè)字母、中間字符的個(gè)數(shù)(.middle.short)、中間的若干字符(.middle.long)、單詞的最后1個(gè)字母。因?yàn)閯?dòng)畫(huà)時(shí)將交替顯示“中間字符的個(gè)數(shù)”和“中間的若干字符”,所以為它們?cè)O(shè)置了特殊類(lèi)名,以便在隨后的 css 代碼中引用它們,當(dāng)要同時(shí)選擇它們時(shí),就用它們共同的類(lèi)名 middle,當(dāng)要分別選擇時(shí),就指定它們各自的類(lèi)名 short 和 long: i
18
nternationalizatio
n 令容器居于頁(yè)面正中: 讓 4 個(gè) 標(biāo)簽包含的文字橫向排列在容器中部: 把 2 個(gè)中間的 元素的文字上色,突出顯示它們: 接下來(lái)制作交互動(dòng)畫(huà)效果。 先把中間的若干字符隱藏起來(lái),只顯示中間字符的個(gè)數(shù),在 html 代碼中找到 .middle.long 元素,為它增加一個(gè) hide 樣式類(lèi): 在 css 中將 .middle.hide 元素的寬度設(shè)置為 0,并且不顯示超出容器的部分: 令鼠標(biāo)懸停在單詞上時(shí),鼠標(biāo)指針變成一只手,提示用戶此時(shí)可以點(diǎn)擊: 為 .word 元素增加鼠標(biāo)點(diǎn)擊事件,當(dāng)單詞被點(diǎn)擊時(shí),2 個(gè)中間元素分別切換 hide 類(lèi),交替顯示兩者中的一個(gè)元素,這些代碼寫(xiě)在一個(gè)名為 initWordElement() 的方法中。在頁(yè)面載入時(shí)將執(zhí)行 init() 方法,再在其中調(diào)用 initWordElement() 方法。沒(méi)有讓 window.onload 直接執(zhí)行 initWordElement() 方法,而是通過(guò) init() 來(lái)調(diào)用,是因?yàn)樵陧?yè)面初始化階段還會(huì)要做一些其他操作,后面還會(huì)逐漸充實(shí) init() 方法: 現(xiàn)在,在頁(yè)面上多次點(diǎn)擊單詞,能看到單詞的中間部分不斷切換了,不過(guò)這時(shí)還沒(méi)有動(dòng)畫(huà)效果,接下來(lái)為切換增加緩動(dòng)效果。 先為中間的 2 個(gè)元素設(shè)置寬度,這 2 個(gè)值是手工測(cè)量得到的,這不是最終的寫(xiě)法,后面我們會(huì)改成用腳本自動(dòng)測(cè)量得到元素的寬度,不過(guò)因?yàn)楝F(xiàn)在我們要解決的是動(dòng)畫(huà)效果,所以先臨時(shí)硬編碼一下: 加緩動(dòng): 設(shè)置緩時(shí)長(zhǎng)為 1 秒: 現(xiàn)在,點(diǎn)擊單詞時(shí)的切換效果,已經(jīng)有了動(dòng)畫(huà)過(guò)程,接下來(lái)細(xì)化動(dòng)畫(huà)效果。 切換可以理解由 2 個(gè)動(dòng)作組成:一個(gè)中間元素消失,另一個(gè)中間元素出現(xiàn),通過(guò)增加緩動(dòng)延時(shí)來(lái)實(shí)現(xiàn)這個(gè)效果: 現(xiàn)在,當(dāng)改變?cè)貙挾葧r(shí),是以元素的左側(cè)為起點(diǎn)改變寬度的,不夠漂亮,我們把它改成以中間為中點(diǎn)改變寬度,這樣當(dāng)元素變寬時(shí),就向兩側(cè)延伸,當(dāng)元素變窄時(shí),就向中間收縮: 接下來(lái)修改緩動(dòng)時(shí)長(zhǎng),由 1s 縮短為 0.5s,也就是令動(dòng)畫(huà)速度加快一倍。為了能方便調(diào)試和維護(hù),我們把時(shí)長(zhǎng)的值定義為變量 --t: 至此,動(dòng)畫(huà)效果制作完成。 “數(shù)略詞”有很多,為了能夠一次展示多個(gè)單詞,我們將對(duì)現(xiàn)有的程序進(jìn)行擴(kuò)展。 先引入 lodash 庫(kù),我們將利用它提供的一個(gè)模板函數(shù)來(lái)處理 html 模板: 擴(kuò)展 dom 結(jié)構(gòu),.container 容器中將包含不止一個(gè) .word 元素,而是多個(gè) .word 元素了。 創(chuàng)建一個(gè) html 模板,它的內(nèi)容是 .word 元素的代碼,其中的第一個(gè)字母、中間字符個(gè)數(shù)、中間的若干字符、最后一個(gè)字母,這些內(nèi)容在模板中分別用變量 first、middleLength、middle、last 表示: 而原 .container 元素中的內(nèi)容都要?jiǎng)h除掉,以便動(dòng)態(tài)填充: 寫(xiě)一個(gè)名為 getWordObject() 的獲取單詞對(duì)象的函數(shù),輸入是一個(gè)單詞,如“internationalization”,輸出是一個(gè)對(duì)象,這個(gè)對(duì)象的屬性與 html 模板中的變量相對(duì)應(yīng): 接下來(lái)寫(xiě)一個(gè)名為 createWordElement() 的方法,用于創(chuàng)建一個(gè) .word 元素,在這個(gè)方法中使用了 lodash 的 _.template() 模板函數(shù)。該方法的輸入是一個(gè)單詞,將傳遞給 getWordObject() 函數(shù): 在負(fù)責(zé)頁(yè)面初始化的 init() 方法中調(diào)用 createWordElement() 方法,整個(gè)流程改為先創(chuàng)建一個(gè)元素,然后把該元素添加到 .container 容器中,再初始化這個(gè)元素: 現(xiàn)在,運(yùn)行一下頁(yè)面,雖然運(yùn)行效果沒(méi)有任何變化,但是 css 的屬性、頁(yè)面元素都已經(jīng)變成動(dòng)態(tài)生成的了。如果把 init() 方法中的 word 變量值改為其他單詞,如 “accessibility”,頁(yè)面中就會(huì)顯示 “a11y” 不過(guò),在單詞變?yōu)?“a11y” 之后,中間元素占據(jù)的寬度就不正確了,這是因?yàn)榇饲爸虚g元素的寬度是硬編碼的,需要把它們改為用腳本賦值。先刪除掉 css 中的這 2 行代碼: 然后為 .middle 元素設(shè)置寬度屬性,屬性值是名為 --w 的變量: 然后在 initWordElement() 方法中增加一行,為變量 --w 賦值: 好了,現(xiàn)在不論把單詞換成什么,都能合適地展現(xiàn)了,至此,單個(gè)單詞的動(dòng)態(tài)改造就完成了。 接下來(lái)請(qǐng)孫大圣拔下幾根毫毛,幫我們把一個(gè)單詞變成多個(gè)單詞吧。 修改 init() 方法,刪除掉 word 變量,定義一個(gè)名為 WORDS 的數(shù)組,遍歷這個(gè)數(shù)組,為數(shù)組中的每個(gè)單詞創(chuàng)建一個(gè) .word 元素: 現(xiàn)在,頁(yè)面上已經(jīng)有 5 個(gè)單詞了,點(diǎn)擊那個(gè) “p43s” 看看世界上最長(zhǎng)的單詞吧。 最后,因?yàn)? 元素的外邊距較大,把它調(diào)整得小一點(diǎn),讓縱向的幾個(gè)單詞排列得緊湊一點(diǎn): 大功告成! 文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。 轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104639.htmlbody {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-image: linear-gradient(bisque, lightcyan);
}
.container {
width: 100%;
}
.word {
font-size: 35px;
font-family: monospace;
display: flex;
justify-content: center;
}
.middle {
color: tomato;
}
.middle {
overflow: hidden;
}
.middle.hide {
width: 0;
}
.word:hover {
cursor: pointer;
}
window.onload = init
function init() {
let el = document.querySelector(".word")
initWordElement(el)
}
function initWordElement(el) {
let middles = el.querySelectorAll(".middle")
el.onclick = () => middles.forEach(m => m.classList.toggle("hide"))
}
.middle {
transition: 1s;
}
.middle.short {width: 42px;}
.middle.long {width: 378px;}
.middle {
transition: 1s;
}
.middle {
transition: 1s;
transition-delay: 1s;
}
.middle.hide {
transition: 1s;
}
.middle {
position: relative;
}
.middle span {
position: absolute;
transform: translateX(0);
transition: 1s;
transition-delay: 1s;
}
.middle.hide span {
transform: translateX(-50%);
transition: 1s;
}
.word {
--t: 0.5s;
}
.middle {
transition: var(--t);
transition-delay: var(--t);
}
.middle span {
transition: var(--t);
transition-delay: var(--t);
}
.middle.hide {
transition: var(--t);
}
.middle.hide span {
transition: var(--t);
}
function getWordObject(w) {
return {
first: w.slice(0, 1),
last: w.slice(-1),
middle: w.slice(1, -1),
middleLength: w.slice(1, -1).length,
}
}
function createWordElement(word) {
const TEMPLATE = document.querySelector("#template").innerHTML
let el = document.createElement("div")
el.className = "word"
el.innerHTML = _.template(TEMPLATE)(getWordObject(word))
return el
}
function init() {
let word = "internationalization"
let el = createWordElement(word)
document.querySelector(".container").appendChild(el)
initWordElement(el)
}
了。/* .middle.short {width: 42px;}
.middle.long {width: 378px;} */
.middle {
width: var(--w);
}
function initWordElement(el) {
let middles = el.querySelectorAll(".middle")
middles.forEach(m =>
m.style.setProperty("--w",
window.getComputedStyle(m.querySelector("span")).width))
el.onclick = () => middles.forEach(m => m.classList.toggle("hide"))
}
function init() {
const WORDS = [
"localization",
"accessibility",
"internationalization",
"supercalifragilisticexpialidocious",
"pneumonoultramicroscopicsilicovolcanoconiosis"
]
WORDS.forEach(word => {
let el = createWordElement(word)
document.querySelector(".container").appendChild(el)
initWordElement(el)
})
}
.word p {
margin: 0.3em 0;
}
摘要:本項(xiàng)目將制作一個(gè)交互動(dòng)畫(huà)效果,令其在單詞原詞和數(shù)略詞之間切換。二擴(kuò)展應(yīng)用到多個(gè)單詞數(shù)略詞有很多,為了能夠一次展示多個(gè)單詞,我們將對(duì)現(xiàn)有的程序進(jìn)行擴(kuò)展。 showImg(https://segmentfault.com/img/bVbtPjm?w=400&h=401); 效果預(yù)覽 按下右側(cè)的點(diǎn)擊預(yù)覽按鈕可以在當(dāng)前頁(yè)面預(yù)覽,點(diǎn)擊鏈接可以全屏預(yù)覽。 https://codepen.io/co...
摘要:本項(xiàng)目將制作一個(gè)交互動(dòng)畫(huà)效果,令其在單詞原詞和數(shù)略詞之間切換。二擴(kuò)展應(yīng)用到多個(gè)單詞數(shù)略詞有很多,為了能夠一次展示多個(gè)單詞,我們將對(duì)現(xiàn)有的程序進(jìn)行擴(kuò)展。 showImg(https://segmentfault.com/img/bVbtPjm?w=400&h=401); 效果預(yù)覽 按下右側(cè)的點(diǎn)擊預(yù)覽按鈕可以在當(dāng)前頁(yè)面預(yù)覽,點(diǎn)擊鏈接可以全屏預(yù)覽。 https://codepen.io/co...
摘要:過(guò)往項(xiàng)目年月份項(xiàng)目匯總共個(gè)項(xiàng)目年月份項(xiàng)目匯總共個(gè)項(xiàng)目年月份項(xiàng)目匯總共個(gè)項(xiàng)目年月份項(xiàng)目匯總共個(gè)項(xiàng)目年月份項(xiàng)目匯總共個(gè)項(xiàng)目年月份項(xiàng)目匯總共個(gè)項(xiàng)目年月至年月發(fā)布的項(xiàng)目前端每日實(shí)戰(zhàn)專欄每天分解一個(gè)前端項(xiàng)目,用視頻記錄編碼過(guò)程,再配合詳細(xì)的代碼解讀, 過(guò)往項(xiàng)目 2018 年 9 月份項(xiàng)目匯總(共 26 個(gè)項(xiàng)目) 2018 年 8 月份項(xiàng)目匯總(共 29 個(gè)項(xiàng)目) 2018 年 7 月份項(xiàng)目匯總(...
閱讀 1695·2021-11-24 09:39
閱讀 2468·2021-11-18 10:07
閱讀 3657·2021-08-31 09:40
閱讀 3316·2019-08-30 15:44
閱讀 2627·2019-08-30 12:50
閱讀 3648·2019-08-26 17:04
閱讀 1429·2019-08-26 13:49
閱讀 1262·2019-08-23 18:05