網(wǎng)站鏈接做投票鄭州全域靜態(tài)管理
自我感覺(jué)沒(méi)有班味!!!每天還是快快樂(lè)樂(lè)上班哇,是愉快的一周~這周沒(méi)有太多活咯,基本就是修修改改改代碼+學(xué)習(xí)。真的感覺(jué)自己寫(xiě)的代碼就是亂七八糟,只要能跑起來(lái)有效果就行(我不是合格的處女座哈哈哈怎么能這么寬容)。然后呢就把寫(xiě)的一個(gè)動(dòng)畫(huà)反復(fù)修改,有點(diǎn)“艱難”(我好慢哦),每次改都是不一樣的問(wèn)題,其實(shí)收獲還蠻多的。
1.第一版
先來(lái)看看第一版,慘不忍睹的代碼.......我自己還覺(jué)得寫(xiě)的挺好,其實(shí)這個(gè)連預(yù)期效果都沒(méi)出來(lái)呢(好丟人)。存在的問(wèn)題目前先說(shuō)這幾個(gè):
- 代碼沒(méi)有語(yǔ)義化(比如id和class命名不夠明確)
- 沒(méi)有代碼注釋(不知道寫(xiě)的代碼是為了干什么)
- 節(jié)點(diǎn)選擇有全局污染(document.querySelector選擇到的是項(xiàng)目里面全部具有這個(gè)類(lèi)名的節(jié)點(diǎn)!)
- 函數(shù)代碼行過(guò)多(讓人看過(guò)去很難理解都做了什么)
<template><div class="scroll" id="scroll"><div class="scroll__animation"><video :src="video.src" muted autoplay preload id="scroll-video"></video><div class="scroll__video-placeholder"></div></div><div class="scroll__text-container" id="scroll-text-container"><div class="scroll__text-section"><slot name="text"></slot></div></div></div>
</template><script lang="ts" setup>import { onMounted, ref } from 'vue';defineProps({video: {default: () => ({src: '',}),},});onMounted(() => {const textSections = Array.from(document.querySelectorAll('.scroll__text-section'));const videoElement = document.getElementById('scroll-video');const textContainer = document.getElementById('scroll-text-container');const videoLoadingDelay = xx;const setUpScrollBehavior = () => {videoElement.pause();videoElement.currentTime = 0;if (videoElement.readyState > 0) {document.querySelector('.scroll__animation').style =xxxx;document.querySelector('.scroll__video-placeholder').style.opacity = '0';const videoDuration = videoElement.duration;const textContainerRect = textContainer.getBoundingClientRect(); const animationStartOffset = 0.5;const animationEndOffset = 0.55;const scrollStartPos =xxxx;const scrollEndPos = yyyy;const scrollLength =zzzz;const updateVideoTime = () => {const scrollPercentage = (window.scrollY - scrollStartPos) / scrollLength;const newTime = videoDuration * scrollPercentage;videoElement.currentTime = isNaN(newTime) ? 0 : newTime;};window.addEventListener('scroll', () => {if (window.scrollY >= scrollStartPos && window.scrollY <= scrollEndPos) {window.requestAnimationFrame(updateVideoTime);}});} else {window.setTimeout(() => {setUpScrollBehavior();}, videoLoadingDelay);}};setUpScrollBehavior();});
</script>
那就看看怎么一步一步修改吧!
2.第二版(語(yǔ)義化)
其實(shí)在第一版的class和id以及定義的變量和函數(shù)名都不太規(guī)范,在命名的時(shí)候盡量把命名更加語(yǔ)義化,讓人看一眼就知道這個(gè)是用于哪里、做什么的。下面是常用的的三種命名方法。
(1)BEM命名法
- Block: 塊。頁(yè)面上的獨(dú)立組成部分,例如.header。
- Element: 元素。Block內(nèi)的組成部分,例如.header__logo。
- Modifier: 修飾符。修改Block或Element的狀態(tài),例如.header--fixed。
- 塊__元素__修飾符:product__button--recommanded。
- 如果一個(gè)單詞不足以表達(dá),就使用“-”隔開(kāi),比如product-card__purchase-button--has-background。
- 適用于: 最適合CSS的class和id命名法。
(2)駝峰命名法
小駝峰法:
- 當(dāng)變量名或者函數(shù)名是由一個(gè)或者多個(gè)單詞連在一起,第一個(gè)單詞以小寫(xiě)字母開(kāi)始,從第二個(gè)單詞之后每個(gè)首字母都大寫(xiě),沒(méi)有連接符。例如:myFirstName、updateVideoTime
- 適用于: 變量和函數(shù)名,常用于js變量和函數(shù)名。
大駝峰法:
- 每個(gè)單詞的首字母都是大寫(xiě),沒(méi)有連接符。例如DataBaseUser。
- 適用于: 在許多編程語(yǔ)言中用于類(lèi)名、接口名、構(gòu)造函數(shù)、函數(shù)名等。
(3)下劃線命名法
- 單詞之間全部采用下劃線連接,都采用小寫(xiě)字母。例如page_header
- 適用情況: 某些語(yǔ)言和庫(kù)中,如Python 。偶爾用于class命名。
所以最適合用于css的class和id命名還是BEM命名法。
由此可以將第一版不明確的class和id命名:
<template><div class="scroll" id="scroll"><div class="scroll__animation"><video :src="video.path" id="scroll-video"></video><div class="scroll__video-placeholder"></div></div><div class="scroll__text-container" id="scroll-text-container"><div class="scroll__text-section"><slot name="text"></slot></div></div></div>
</template>
改為如下命名:
<template><div class="animation-text-scroll" id="animation-text-scroll"><div class="animation-text-scroll__animation"><video :src="video.path" id="animation-text-scroll__video"></video><div class="animation-text-scroll__video-placeholder"></div></div><div class="animation-text-scroll__text-container" id="animation-text-scroll__text-container"><div class="animation-text-scroll__text-section"><slot name="content"></slot></div></div></div>
</template>
3.第三版(代碼注釋)
接下來(lái)是關(guān)于代碼注釋的??梢钥吹街皩?xiě)的代碼我是一點(diǎn)注釋沒(méi)寫(xiě)哇(除了自己知道寫(xiě)的什么,可能時(shí)間越久自己也忘了寫(xiě)的啥)。想一下當(dāng)你接手某個(gè)人寫(xiě)的代碼,一點(diǎn)注釋也沒(méi)寫(xiě),那得好好吐槽咯......主要有以下幾點(diǎn):
- 避免顯而易見(jiàn)的注釋:如果代碼本身就非常直觀,就不需要額外的注釋
- 文檔注釋:用于描述函數(shù)、方法或類(lèi)的作用和用法。
/*** 設(shè)置滾動(dòng)行為,根據(jù)滾動(dòng)位置的百分比調(diào)整視頻的播放進(jìn)度*/
const setUpScrollBehavior = () => {...};
- 解釋性注釋:用于解釋代碼中非顯而易見(jiàn)的部分。
// 觸發(fā)滾動(dòng)行為之前,將視頻狀態(tài)初始化,確保視頻播放與滾動(dòng)行為同步
videoElement.pause();
videoElement.currentTime = 0;
- 警告性注釋:用于指出需要注意的地方,比如潛在的問(wèn)題或遺留代碼。
4.第四版(節(jié)點(diǎn)選擇,避免全局污染)
在最開(kāi)始使用document.getElementById和document.querySelector其實(shí)選擇的都是整個(gè)項(xiàng)目里面具有這個(gè)類(lèi)名和id的DOM節(jié)點(diǎn),其實(shí)你想選擇的只是這個(gè)組件里面的DOM節(jié)點(diǎn)。那怎么只選擇到當(dāng)前組件的節(jié)點(diǎn)呢?
- 第一種思路是使用ref,給需要選擇到的節(jié)點(diǎn)打上ref標(biāo)識(shí)。然后使用ref定義的命名來(lái)獲取相應(yīng)的dom節(jié)點(diǎn)。(有點(diǎn)小問(wèn)題)
<template><div><video ref="videoElement"></video></div>
</template><script lang="ts" setup>import { onMounted, ref } from 'vue';const videoElement = ref(null);onMounted(() => {console.log(videoElement.value);videoElement.value.pause();});
</script>
- 第二種方法(推薦)是先通過(guò) getCurrentInstance返回當(dāng)前Vue組件實(shí)例,在通過(guò) getCurrentInstance.ctx.$el獲取當(dāng)前Vue組件實(shí)例的根DOM元素。 一旦獲得了組件的根DOM元素,就可以使用DOM API(如querySelector和querySelectorAll,querySelector('#id') 或者querySelector('.類(lèi)名'))來(lái)選擇該組件內(nèi)的元素。
onMounted(() => {const currentDocument = getCurrentInstance().ctx.$el;const textSections = Array.from(currentDocument.querySelectorAll('.index-scroll__text-section'));const videoElement = currentDocument.querySelector('#index-scroll-video');
});
5.第五版(代碼行數(shù)優(yōu)化)
經(jīng)過(guò)幾次修改感覺(jué)沒(méi)問(wèn)題了,但是還有一個(gè)很重要的沒(méi)有修改!一般函數(shù)的代碼行數(shù)不超過(guò)20行,但是會(huì)發(fā)現(xiàn)我寫(xiě)的onMounted鉤子函數(shù)里面代碼非常多,一下子看過(guò)去也不知道在干嘛!那要怎么優(yōu)化呢?
將一件事情拆分細(xì)化為幾件不同的事件,然后在onMounted里面按照這個(gè)順序調(diào)用就好了。總體來(lái)說(shuō)做的事情有以下幾件:
(1)獲取必要節(jié)點(diǎn)
(2)視頻初始化。const setVideoInitStatus = () =>{};
(3)等待視頻準(zhǔn)備好(就讀取相關(guān)數(shù)據(jù))。const waitVideoReady = () => {};
(4)讀取滾動(dòng)相關(guān)數(shù)據(jù),為計(jì)算做準(zhǔn)備。const setUpScrollBehavior = () => {};
(5)監(jiān)聽(tīng)滾動(dòng)范圍是否在動(dòng)畫(huà)范圍內(nèi)(更新視頻時(shí)間)
(6)更新視頻時(shí)間。const updateVideoTime = () => {};
然后將onMounted里面的事件拆分為這幾個(gè),就一目了然了。
onMounted(() => {// 獲取必要節(jié)點(diǎn)currentDocument = getCurrentInstance().ctx.$el;textSections = Array.from(currentDocument.querySelectorAll('.index-scroll__text-section'));videoElement = currentDocument.querySelector('#index-scroll-video');textContainer = currentDocument.querySelector('#index-scroll-text-container');videoLoadingDelay = navigator.connection ? Math.max(1750 / navigator.connection.downlink, 150) : 300;// 視頻初始化setVideoInitStatus();// 等待視頻準(zhǔn)備好(就讀取相關(guān)數(shù)據(jù))waitVideoReady(setUpScrollBehavior);// 監(jiān)聽(tīng)滾動(dòng)范圍是否在動(dòng)畫(huà)范圍內(nèi)(更新視頻時(shí)間)window.addEventListener('scroll', () => {if (window.scrollY >= scrollStartPos && window.scrollY <= scrollEndPos) {window.requestAnimationFrame(updateVideoTime);}});
});
- 其實(shí)還有一個(gè)點(diǎn),因?yàn)樵诓煌暮瘮?shù)作用域里面,變量是無(wú)法訪問(wèn)到的。(好吧又是作用域)所以要在使用變量之前,先在全局作用域里面聲明變量,比如let videoElement; 其他函數(shù)里面videoElement = xxxxx; 給變量賦值就相當(dāng)于給全局作用域的變量修改了值。全局作用域的變量其他函數(shù)都可以訪問(wèn)了。
6.寫(xiě)在最后
- 本周自評(píng)6分,學(xué)習(xí)沒(méi)認(rèn)真學(xué),工作干的也不好......
- 昨天竟然又?jǐn)鄶嗬m(xù)續(xù)睡了一天,晚上才清醒,顛倒晝夜的生活哇
- 今天不能這樣咯,出去走走....(我好像那種老年人,好淡的生活)
- 下個(gè)月就立秋咯,不過(guò)這里依然是夏天~挺好的
- 拜拜,淡淡的一周,下周擼起袖子加班學(xué)習(xí)(哈哈哈期待沒(méi)想到加班不是為了工作而是為了學(xué)習(xí))!