【前端html页面练习】还原英雄联盟客户端
對本文內(nèi)容的說明:
由于該練習(xí)文章其實是筆者剛學(xué)習(xí)完 Vue 就來寫的小項目,所以該文章的實現(xiàn)方式在現(xiàn)在看來,是十分復(fù)雜且繁瑣的,而且代碼寫的也十分混亂,頁面無法實現(xiàn)兼容性,使用了 HTML、CSS、JavaScript、jQuery、Vue ,因此源碼肯定對各位幫助不大。文章內(nèi)容主要就是記錄了當(dāng)時遇到的一些問題和樣式上的內(nèi)容。因此該文章主要就是個練習(xí)和總結(jié)文,方便之后遇到相關(guān)問題后能迅速找到解決方案。由于大家還是想要源碼和相關(guān)資源,所以最后還是決定給大家貼出來。
但是重要的事情說三遍,該源碼真的僅供各位參考,僅供參考!僅供參考!僅供參考!寫的真的很差。所以推薦大家用 Vue項目 + ElementUI 去寫。
文中的靜態(tài)資源,各位如有需要可去評論區(qū)自行下載(除了在游戲安裝路徑下的圖之外,都是自己在游戲上截圖的)。
本文免費源代碼點擊👉鏈接👈即可進入下載頁面 (再次說明:該源碼寫的真的很差,僅供參考,到各位的瀏覽器上不一定能正常顯示)。
歡迎大家前往 我的 Vue 專欄 了解更多關(guān)于 Vue 的內(nèi)容。
在仿寫客戶端的過程中,我使用了 HTML、CSS、JavaScript、jQuery、Vue
其中JS和jQuery用來實現(xiàn)DOM操作(主要還是用jQuery)
由于在寫本文章的時候,筆者還處于學(xué)習(xí)狀態(tài),模仿客戶端界面是一時興起,想著做點什么練練手,看看各種復(fù)雜的功能該如何實現(xiàn),也沒有接觸過項目,不知道規(guī)范,因此才混合起來使用這些技術(shù)。但從目前來看,確實是太稚嫩了。所以推薦大家不要像源碼中那樣寫(多去學(xué)習(xí)使用 Vue 或者 React + 各種組件)。
而且在編寫代碼前,我對Vue的理解是很片面的,認(rèn)為Vue最大的用處就是編寫單頁面應(yīng)用,而我在思考的過程中覺得仿寫客戶端需要多頁面的跳轉(zhuǎn),因此最終沒有選擇采用Vue項目的形式。后來查詢了一下,Vue項目應(yīng)該也能實現(xiàn)多頁面應(yīng)用,不過這方面的問題只能以后嘗試了。
因此我沒有搭建Vue項目,那么做DOM操作,我還是覺得jQuery更簡單,因此使用jQuery。然后用Vue來綁定事件及實現(xiàn)一些功能(在文章中會提到)。
然后說回到代碼本身,它是有瀏覽器兼容性問題的,而且解決瀏覽器兼容性這方面是我的弱項。在代碼中我嘗試使用%的方式,來確保內(nèi)容可以根據(jù)瀏覽器的寬高來等比例縮小或放大,但從結(jié)果上來看…em…差強人意,但至少一多半的內(nèi)容都能正常展現(xiàn)。而且最開始的感覺還挺良好的,以為找到了還算不錯的解決方案。不過能出現(xiàn)差錯也代表著編寫的代碼是有一定問題的。以后再嘗試的話,會采用rem試試看,并盡量編寫更好的代碼。
不過游戲客戶端本身就是無法拉伸的,本著這樣的想法,最后還是用%完成了在Chrome瀏覽器的,指定頁面大小下的布局(其他瀏覽器我在嘗試的時候,確實是有兼容性問題)
(也就是說,我考慮了兼容性問題,結(jié)果在本次編寫代碼過程中,還是無法解決…)
我在編寫代碼過程中的相關(guān)素材取自:
Iconfont-阿里巴巴矢量圖標(biāo)庫
覓元素
主要素材來源:
游戲下載路徑\英雄聯(lián)盟\TCLS\ui\res\test
游戲下載路徑\英雄聯(lián)盟\TCLS\ui\servers
游戲下載路徑\英雄聯(lián)盟\TCLS\ui\movie_tpf\img
游戲下載路徑\英雄聯(lián)盟\TCLS\ui\media
游戲下載路徑\英雄聯(lián)盟\Air\assets\images
游戲下載路徑\英雄聯(lián)盟\Air\assets\storeImages
說到這些素材,當(dāng)我編寫登錄界面的時候,以為所有樣式內(nèi)容都需要用css來實現(xiàn),結(jié)果到了后面感覺很多樣式都編寫不出來時才發(fā)現(xiàn),原來…我之前辛辛苦苦自己做的樣式,lol都是有相關(guān)素材的。因此,我們只要能找到素材,那我們要做的就只是定位,綁定事件即可,其實還是蠻簡單的。除此以外,因為我切圖手法比較笨拙,所以后期有一些都是我直接從客戶端上拿下來的。
進入內(nèi)容前,直接上演示視頻:(只實現(xiàn)了 登錄 到 主界面)
【前端】仿寫LOL客戶端界面(演示視頻)
前端模仿英雄聯(lián)盟客戶端界面
- 帳號登錄界面
- 背景圖(img和background-image)
- 按鈕顏色漸變
- 加載效果(轉(zhuǎn)動)
- 從 安全檢測 轉(zhuǎn)成 登錄方式(頁面部分內(nèi)容的變化)
- 圖標(biāo)控制音樂開關(guān)
- 登錄功能
- 選擇服務(wù)器界面
- Vue的過渡效果(transition標(biāo)簽)
- 排隊加載界面
- 進度條的實現(xiàn)
- 游戲客戶端主頁面
- 初次進入客戶端的廣告
- 移入移出效果(mouseenter、mouseleave)
- 好友列表的展開效果
- 視頻的自動播放問題
- 輪播圖的實現(xiàn)
帳號登錄界面
對于頁面設(shè)計,我個人的經(jīng)驗之談就是,先劃分區(qū)域并開啟絕對定位,然后讓每個區(qū)域都處在對應(yīng)的位置上。比如該部分的頁面,我把它劃分成了三個部分。劃分好區(qū)域后,所有的內(nèi)容都會在各自的區(qū)域中排布。
左上區(qū)域涉及到的用法:img和background-image的用法、按鈕漸變效果
左下方區(qū)域的文字內(nèi)容,本來我是自己貼圖 + 用三個div設(shè)計的,后來發(fā)現(xiàn)lol素材里,它有一整張圖片(除了紅色邊框中的內(nèi)容外),那就直接拿來用了。紅色邊框內(nèi)的文字,是一段超鏈接,我們只需要給它定位就可以了。
右側(cè)區(qū)域涉及到的用法:加載效果(轉(zhuǎn)動)、區(qū)域內(nèi)容的轉(zhuǎn)化、音樂的開關(guān)、登錄功能
在右側(cè)區(qū)域,下面看到的logo的動態(tài)效果是lol的素材。
注:img可以加載gif圖片,因此這里才是動態(tài)效果,而如果是webm格式的,就比較麻煩了,在之后會提到這方面的問題。
背景圖(img和background-image)
<!--左側(cè)區(qū)域--><div class="left"><!--聯(lián)盟圖標(biāo)--><div class="logo"><img src="./img/login-icon/logo-public.png"/></div></div> /*左側(cè)顯示區(qū)域的整體樣式*/.left{position: absolute;width: 80%;height: 94%;left: 0;background-image: url("./img/login-icon/login_page.jpg");background-repeat: no-repeat;background-size: cover;}/*英雄聯(lián)盟圖標(biāo)樣式*/.logo{position: absolute;width: 95%;border-bottom: 1px darkgoldenrod solid;left: 2.5%;}最開始學(xué)習(xí)的時候,我覺得img是使用圖片的最好方法,但是當(dāng)遇到越來越多的需求的時候,我發(fā)現(xiàn)background-image的方式更應(yīng)該被靈活運用,而且可以解決很多麻煩。
比如,在這個部分我就分別用了這兩種方式。在我看來,它們的使用條件幾乎沒什么區(qū)別。
如果該圖片是和文字在一行中或者一列中排列的,那么使用img是比較好的(從代碼量上來看,性能方面未知)。因為用div設(shè)置背景,除去定位,一定要設(shè)置寬度高度,background-size和background-image。而對于img,除去定位,只需要設(shè)置寬度 / 高度 其中一項,圖片就可以等比例縮放、放大。
(對于行內(nèi)元素,只有在標(biāo)簽內(nèi)寫了一些內(nèi)容,背景才會顯示,而且無法設(shè)置背景相關(guān)信息。因此如果想把行內(nèi)元素變成塊元素,那不如直接用div設(shè)置)
比如:
在這種用法里,外部容器div被我用紅色背景顯示。這個外部容器在這種情況下,可以不用設(shè)置height,除非項目中指定高度。那么這樣一來,div的高度會被內(nèi)容撐起。這里能設(shè)置的樣式就很多了,比如文字和圖片之間有間距,只需要設(shè)置margin;文字和圖片使用居中方案;又或是修改圖片大小并定位。
如果是把圖片當(dāng)作背景,確實是使用background會更好,因為外部容器div設(shè)置了背景,那么內(nèi)部所有元素都只需要在這外部容器中操作。但是當(dāng)然img也能當(dāng)背景,只不過這些元素肯定是不能放在img標(biāo)簽內(nèi)了,只能再另建一個容器,把內(nèi)容放在img上,讓img的z-index更小,那顯然這種方式不利于維護。
也就是說,其實這兩種在任何情況下都還算是可以轉(zhuǎn)換使用的,但是使用background顯然是可以設(shè)置更多屬性的去解決很多問題的。
區(qū)別還是有一些的:
如果圖片事先知道尺寸大小,且想完整顯示,那么就需要設(shè)置根標(biāo)簽的寬度、高度。如果不知道卻依然堅持用background,要不就是自己手動調(diào)整寬度高度,要不就是用background-size: cover 圖片多出的部分會刪去,background-size: contain 標(biāo)簽中會出現(xiàn)空白的部分。那么用img就可以設(shè)置寬度 / 高度 任一屬性,就可以在不知道尺寸大小的情況下,等比例縮放。
如果遇到CSS Sprites(css精靈圖),那么只能使用background。
如果遇到能點擊的圖片,那么只能使用background。
按鈕顏色漸變
這里所謂的“按鈕”,其實是一個超鏈接a。如果真的使用按鈕,首先為其設(shè)置樣式會稍微麻煩一些,而且點擊按鈕就去展示一個新頁面,不如直接使用超鏈接。
漸變效果采用的是CSS的linear-gradient去設(shè)計,這種方式挺簡單的。更復(fù)雜的可以考慮canvas。
(但是實際上,后來發(fā)現(xiàn)lol的按鈕是圖片效果,在lol素材里可以找到,這就方便很多了)
之后所有的漸變按鈕都是這種方式,下面這個a中的圖片,就是采用上面提到的img方式。
加載效果(轉(zhuǎn)動)
視頻中的加載效果 -> 該效果的教學(xué)視頻
從 安全檢測 轉(zhuǎn)成 登錄方式(頁面部分內(nèi)容的變化)
頁面轉(zhuǎn)化是根據(jù)數(shù)字的變化,當(dāng)安全檢測值到100%,就“跳轉(zhuǎn)”。這部分就很簡單了,數(shù)據(jù)綁定 + v-cloak(防止表達式閃爍)
<!--安全檢測的進度條--><div v-cloak class="finish">{{finish}}%</div>然后在vue的mounted生命周期中,直接設(shè)置定時器,模擬安全檢測效果,并在結(jié)束時清除定時器。
mounted(){/*剛進入頁面就會直接進行安全檢測*/this.intervalTime = setInterval(()=>{this.finish += 20/*當(dāng)安全檢測完成時,跳轉(zhuǎn)到登錄頁面,且清除定時器*/if(this.finish === 100){this.right = falseclearInterval(this.intervalTime)}},1000)},在vue里設(shè)置了一個屬性right,其初始值是true。當(dāng)安全檢測結(jié)束后,right為false,然后觸發(fā)v-if:
<!--右側(cè)安全檢測后的登錄區(qū)域--><div class="right" v-if="!right">....</div><!--右側(cè)展示安全登錄檢測框--><div class="right" v-else><!-- 實現(xiàn)安全檢測的動畫 --><div class="container"><!--旋轉(zhuǎn)球效果--><div class="rotate"><!--代表每個球--><div class="item"></div><div class="item"></div><div class="item"></div><div class="item"></div><div class="item"></div></div><!--間隔--><div class="gap"></div><p>正在進行安全檢測:</p><!--安全檢測的進度條--><div v-cloak class="finish">{{finish}}%</div></div></div>那么這種用法將會是之后所有 部分區(qū)域頁面內(nèi)容變化的實現(xiàn)方式 (不是v-if就是用的v-show),也就是模擬出了類似單頁應(yīng)用的效果。而將這兩個div都設(shè)置同一個類,也就保證了切換后,它們最外圍容器的位置、樣式都是一樣的。
但是這種方式肯定不能和vue-router相提并論。首先這種是有切換損耗的,并且不可能實現(xiàn)多次的轉(zhuǎn)換(比如v-if只能用作兩部分內(nèi)容的切換,v-show也類似,但是v-show可以讓多個內(nèi)容同時顯示或隱藏)
圖標(biāo)控制音樂開關(guān)
<!--右上角相關(guān)圖標(biāo)--><div class="right-icon"><!--看不見的播放器--><audio id="player" loop="loop"><source src="./img/login-icon/sound.mp3"/></audio><a href="javascript:;" v-if="ok" @click="music"><img src="./img/login-icon/laba-off.png"/></a><a href="javascript:;" v-else @click="music"><img src="./img/login-icon/laba.png"/></a><a href="javascript:;"><img src="./img/login-icon/suoxiao.png"/></a><a href="javascript:;"><img src="./img/login-icon/guanbi.png"/></a></div>音頻采用的是audio,只要不給其添加controls屬性,那么在頁面中就看不到這個音樂播放器,我們只要在音樂的圖標(biāo)中,添加一個開關(guān)的v-if(切換圖片)和@click事件,就完成了這部分內(nèi)容。
methods: {music(){ /*音樂相關(guān)信息*/this.ok = !this.okif(this.ok === false){player.src = './img/login-icon/sound.mp3';player.play();}else{player.src = '';player.pause();}}}登錄功能
首先這里 QQ登錄 - 微信登錄、切換至快速登錄 - 使用其它帳號登錄 ,部分內(nèi)容的轉(zhuǎn)換采用的都是v-if。
<!--右側(cè)安全檢測后的登錄區(qū)域--><div class="right" v-if="!right"><!-- 選擇登錄方式之后 --><div class="login-on" v-if="login"><!--上方的兩個選項--><!--QQ選項--><a href="javascript:;" :class="{classA: hasLogin, classB: !hasLogin, classC: true}" @click="qqLogin"><img src="./img/login-icon/qq.png"/>QQ登錄</a><!--微信選項--><a href="javascript:;" :class="{classA: !hasLogin, classB: hasLogin, classD: true}" @click="chatLogin"><img src="./img/login-icon/wechat.png"/>微信登錄</a><!--設(shè)定登錄小三角--><div :class="{triangleQQ: hasLogin, triangleChat: !hasLogin}"></div><!--QQ登錄區(qū)--><div class="QQAction" v-if="hasLogin"><!--正常輸入帳號區(qū)域--><div v-if="quickLogin"><div class="QQAction-color1">QQ帳號</div><input type="text" title="安全提示:騰訊英雄聯(lián)盟不會在登錄或游戲過程中詢問與您帳號有關(guān)的任何密保信息,請謹(jǐn)防騙取密保的盜號木馬" v-model="account"/><div :style="{height: '10px'}"></div><div class="QQAction-color1">QQ密碼</div><input type="password" title="安全提示:騰訊英雄聯(lián)盟不會在登錄或游戲過程中詢問與您帳號有關(guān)的任何密保信息,請謹(jǐn)防騙取密保的盜號木馬" v-model="password"/><br/><div :style="{height: '10px'}"></div><input type="checkbox"/><span class="QQAction-color2">記住賬號</span><br/><input type="checkbox" :checked="hasCheck" @click="hasCheck=!hasCheck"/><span class="QQAction-color2">我已詳細(xì)閱讀并同意</span><br/><a href="https://game.qq.com/contract.shtml" class="QQAction-color3" target="_blank">騰訊游戲用戶協(xié)議</a><span class="QQAction-color2">和</span><a href="https://game.qq.com/privacy_guide.shtml" class="QQAction-color3" target="_blank">隱私保護指引</a><div :style="{height: '10px'}"></div><a href="javascript:;" class="QQAction-color4" @click="gameStart">進入游戲</a><a href="javascript:;" class="QQAction-color5" @click="quickLogin=!quickLogin">切換至快速登錄</a></div><!--快速登錄賬號區(qū)域--><div v-else><div class="QQAction-color1">檢測到您已登錄QQ帳號,請選擇登錄</div><div :style="{height: '10px'}"></div><a href="javascript:;" class="Quick-btn">只爭朝夕不負(fù)韶華(54*****57)</a><div :style="{height: '70px'}"></div><input type="checkbox" :checked="hasCheck" @click="hasCheck=!hasCheck"/><span class="QQAction-color2">我已詳細(xì)閱讀并同意</span><br/><a href="https://game.qq.com/contract.shtml" class="QQAction-color3" target="_blank">騰訊游戲用戶協(xié)議</a><span class="QQAction-color2">和</span><a href="https://game.qq.com/privacy_guide.shtml" class="QQAction-color3" target="_blank">隱私保護指引</a><div :style="{height: '10px'}"></div><a href="javascript:;" class="QQAction-color4" @click="quickStart">確定</a><a href="javascript:;" class="QQAction-color5" @click="quickLogin=!quickLogin">使用其它帳號登錄</a></div></div><!--微信登錄區(qū)--><div class="wechatAction" v-else><div class="QQAction-color2">使用 微信掃碼 安全登錄</div><div :style="{height: '10px'}"></div><img src="./img/login-icon/QR.png"/><a href="javascript:;" class="re"></a><div :style="{height: '20px'}"></div><input type="checkbox" /><span class="QQAction-color2">我已詳細(xì)閱讀并同意</span><br/><a href="https://game.qq.com/contract.shtml" class="QQAction-color3" target="_blank">騰訊游戲用戶協(xié)議</a><span class="QQAction-color2">和</span><a href="https://game.qq.com/privacy_guide.shtml" class="QQAction-color3" target="_blank">隱私保護指引</a></div></div><!-- 進入頁面選擇登陸方式 --><div v-else><!--選擇QQ--><a href="javascript:;" class="QQLogin" @click="qqLogin"><img src="./img/login-icon/qq.png"/>QQ登錄</a><!--選擇微信--><a href="javascript:;" class="wechatLogin" @click="chatLogin"><img src="./img/login-icon/wechat.png"/>微信登錄</a></div></div>然后是Vue中全部內(nèi)容:
<script type="text/javascript">new Vue({el: '#lol',data: {ok: true, //用來判斷喇叭是否開啟right: true, //用來判斷是否在進行安全檢測finish: 0, //用來判斷安全檢測的進度login: false, //選擇一種登錄方式,且login為true后永遠(yuǎn)不變回去hasLogin: true, // true是QQ登陸,false是微信登錄,默認(rèn)QQaccount: '', //記錄帳號password: '', //記錄密碼hasCheck: false, //判斷相關(guān)說明是否已經(jīng)框選quickLogin: true //判斷是否進行快速登錄},mounted(){/*剛進入頁面就會直接進行安全檢測*/this.intervalTime = setInterval(()=>{this.finish += 20/*當(dāng)安全檢測完成時,跳轉(zhuǎn)到登錄頁面,且清除定時器*/if(this.finish === 100){this.right = falseclearInterval(this.intervalTime)}},1000)},methods: {music(){ /*音樂相關(guān)信息*/this.ok = !this.okif(this.ok === false){player.src = './img/login-icon/sound.mp3';player.play();}else{player.src = '';player.pause();}},qqLogin(){ /*選擇QQ登錄*/if(this.login === false){this.login = true}if(this.hasLogin === true){}else{this.hasLogin = true}},chatLogin(){ /*選擇微信登錄*/if(this.login === false){this.login = true}if(this.hasLogin === false){}else{this.hasLogin = false}},gameStart(){ //正則表達式,判斷賬號密碼是否符合規(guī)范let reg = /[0-9]{6,}/iglet reg2 = /\S{6,}/igif(reg.test(Number(this.account))&®2.test(this.password)){if(this.hasCheck){alert('登錄成功')/*登錄成功后進入選擇服務(wù)器頁面*/window.location.href="./chooseServer.html"}else{alert('請仔細(xì)閱讀內(nèi)容后,勾選按鈕')}}else{alert('帳號或密碼輸入錯誤')}},quickStart(){ /*快速登錄功能*/if(this.hasCheck){alert('登錄成功')/*登錄成功后進入選擇服務(wù)器頁面*/window.location.href="./chooseServer.html"}else{alert('請仔細(xì)閱讀內(nèi)容后,勾選按鈕')}}}}) </script>那么通過之前的說明,我們要改變部分區(qū)域的內(nèi)容,我們使用v-if就可以實現(xiàn)。也就是當(dāng)我們點擊某個按鈕后,修改了data中的數(shù)據(jù),從而導(dǎo)致v-if v-else觸發(fā),在同一個區(qū)域就展示了不同的內(nèi)容。
想要實現(xiàn):我已詳細(xì)閱讀并同意 被選擇后才能進入下一步,就只需要綁定checked:
<input type="checkbox" :checked="hasCheck" @click="hasCheck=!hasCheck"/><span class="QQAction-color2">我已詳細(xì)閱讀并同意</span>那么設(shè)置成:當(dāng)點擊按鈕,導(dǎo)致hasCheck為true時,才能跳轉(zhuǎn)到下個頁面就完成了該功能。
然后點擊“進入游戲”或“確定”(超鏈接a)后,去判斷是否hasCheck為true,以及如果選擇賬號登陸,賬號密碼是否符合正則表達式即可。最后如果滿足了條件,使用window.location.href"跳轉(zhuǎn)頁面即可。
這里還有一個用法就是實現(xiàn)三角形,這個就是面試中常問到的問題了。
三角形很容易實現(xiàn),只需要寬高設(shè)為0,給一定的border大小,將其設(shè)為透明,然后根據(jù)三角形的朝向設(shè)置color就實現(xiàn)了。比如下面給border-top-color,那就是箭頭朝下。border-bottom-color,那就是箭頭朝上。
然后設(shè)計一個,當(dāng)點擊某登錄方式時,讓箭頭偏移位置就可以實現(xiàn)箭頭也跟著切換的效果了。
除此以外,第一個頁面就都是定位和設(shè)置樣式了。
選擇服務(wù)器界面
整體效果:
該界面比較簡單,如何劃分區(qū)域都可以,把它看成一個區(qū)域也行,上下兩個區(qū)域也行。
在這里先說一說我沒實現(xiàn)的功能:
(1)無法點擊大區(qū)圖標(biāo)旁的兩個按鈕實現(xiàn)換區(qū)功能;
(2)在服務(wù)器列表中無法點擊服務(wù)器,去實現(xiàn)換區(qū)功能。
這個功能如果不構(gòu)建Vue項目,感覺實現(xiàn)起來會十分繁瑣,單頁應(yīng)用效果肯定會是最佳選擇,因為這不是單純v-if就能實現(xiàn)的。
在每個服務(wù)器名字前的綠點,是這么實現(xiàn)的:(后來發(fā)現(xiàn),也有這個素材)
/*給所有服務(wù)器前加上綠色標(biāo)志*/.open a::before{content: '◆';color: #1FAE69;margin-right: 10px;}那么該部分除了定位和樣式外,只用到了Vue的過渡效果
Vue的過渡效果(transition標(biāo)簽)
<transition name="serviceOpen"><div class="open" v-show="openService" v-cloak><div class="server-font" :style="{top: '1%'}">全網(wǎng)絡(luò)大區(qū)</div><a href="javascript:;" class="blueServer" :style="{top: '5%'}">男爵領(lǐng)域</a><a href="javascript:;" class="blueServer" :style="{top: '5%', left: '15%'}">峽谷之巔</a><div class="server-font" :style="{top: '15%'}">電信</div><a href="javascript:;" class="yellowServer active" :style="{top: '19%'}">艾歐尼亞</a><a href="javascript:;" class="yellowServer" :style="{top: '19%', left: '15%'}">祖安</a><a href="javascript:;" class="yellowServer" :style="{top: '19%', left: '27%'}">諾克薩斯</a><a href="javascript:;" class="yellowServer" :style="{top: '19%', left: '39%'}">班德爾城</a>...</div></transition>transition標(biāo)簽是Vue中的方法,被該標(biāo)簽包裹的內(nèi)容,就會在內(nèi)容改變時,產(chǎn)生過渡效果。使用方法很簡單,而且頻繁切換也是沒問題的。如果是css中設(shè)置的過渡和動畫效果,是沒辦法實現(xiàn)返程的,也就是說顯示需要觸發(fā)一次,關(guān)閉再觸發(fā)一次。而Vue的transition在設(shè)置的時候,就可以設(shè)計顯示效果和隱藏效果,很方便。
/*服務(wù)器列表動畫*/.serviceOpen-leave-active,.serviceOpen-enter-active{transition: all 1s;}.serviceOpen-leave-to,.serviceOpen-enter{opacity: 0;}排隊加載界面
整個背景采用的是素材,該部分只是向其中添加了文字和進度條。上面兩個場景的變換,依然采用v-if。排隊時間變化依然采用 在mounted生命周期中添加定時器的方式來實現(xiàn)。取消按鈕也和以前一樣。
在這里主要是進度條的實現(xiàn)
完整代碼:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>League of Legends</title><!--設(shè)置網(wǎng)頁圖標(biāo)--><link rel="icon" href="./img/icon/lol2.ico" type="image/x-icon"><style>/*通用設(shè)置*/*{margin: 0;text-decoration: none;list-style: none;}/*防止表達式閃爍*/[v-cloak]{display:none;}/*整體架構(gòu)設(shè)計*/#game{position: absolute;width: 100%;height: 100%;background-repeat: no-repeat;background-size: contain;background-image: url("img/new-icon/wait_icon.png");}/*正在排隊等候*/.wait{position: absolute;color: #F0E7D6;top: 57%;left: 49.5%;transform: translateX(-50%);font-size: 18px;}/*設(shè)置所有span顏色*/span{color: #DDC796;}/*當(dāng)前位置和等待時間通用樣式*/.currentPosition,.waitTime{position: absolute;color: #F7F0E0;left: 45%;font-size: 13px;}.currentPosition{top: 62%;}.waitTime{top: 65%;}.currentPosition span{margin-left: 25px;}/*取消和進行欄*/.cancel{position: absolute;display: block;width: 8%;height: 5%;bottom: 23%;left: 45.2%;text-align: center;line-height: 35px;background-color: #131622;border: 1.5px darkgoldenrod solid;color: #CABD8E;transition-property: all;transition-duration: 0.5s;}.cancel:hover{border: 1.5px #DDC796 solid;color: #F0E5D3;background-image: linear-gradient(rgb(23,30,38),rgb(110,100,74));}/*排隊完成后,進入加載頁面*//*進度條樣式*/.progressContainer{position: absolute;width: 15%;height: 1.2%;top: 62%;left: 42%;border: 1px solid #C4A76C;border-radius: 10px;}#progress{width: 0%;height: 100%;background-image: linear-gradient(to right, rgb(0,90,130),rgb(108,200,210));}</style> </head> <body><div id="game"><!--正在載入--><div v-if="loading" v-cloak><div class="wait">正在載入</div><div class="progressContainer"><div id="progress"></div></div></div><!--正在排隊--><div v-else v-cloak class="waiting"><div class="wait">正在排隊等候</div><div class="currentPosition">當(dāng)前位置:<span v-cloak>{{queueNum}}</span></div><div class="waitTime">預(yù)計等待時間:<span v-cloak>{{minute}}分鐘</span></div><a class="cancel" href="./chooseServer.html">取消</a></div></div></body> <script type="text/javascript" src="js/vue.js"></script> <script src="js/jquery-1.12.3.js" type="text/javascript"></script> <script type="text/javascript">new Vue({el: '#game',data: {queueNum: 77777, //當(dāng)前排隊位置minute: 7, //預(yù)計等待時間loading: false, /*判斷是否開始加載*/w: 0 /*代表當(dāng)前加載進度*/},mounted(){/*剛進入頁面就排隊*/this.intervalTime = setInterval(()=>{this.queueNum -= 11111this.minute -= 1if(this.queueNum === 0){this.loading = true;/*現(xiàn)在轉(zhuǎn)為加載界面*/this.intervalLoad = setInterval(()=>{this.w += 1$('#progress').css('width', this.w +'%')if(this.w === 100){window.location.href="./LOLGame.html";clearInterval(this.intervalLoad)}},100)clearInterval(this.intervalTime)}},1000)}}) </script> </html>進度條的實現(xiàn)
this.intervalLoad = setInterval(()=>{this.w += 1$('#progress').css('width', this.w +'%')if(this.w === 100){window.location.href="./LOLGame.html";clearInterval(this.intervalLoad)}},100)首先定時器設(shè)計的也很簡單,0.1s觸發(fā)一次,屬性w用來記錄進度條的進度,然后根據(jù)w的值,來修改進度條中的進度。當(dāng)該值為100時,跳轉(zhuǎn)頁面,進入到游戲客戶端主頁面。
html部分:
<div class="progressContainer"><div id="progress"></div></div>進度條的css實現(xiàn):
/*排隊完成后,進入加載頁面*//*進度條樣式*/.progressContainer{position: absolute;width: 15%;height: 1.2%;top: 62%;left: 42%;border: 1px solid #C4A76C;border-radius: 10px;}#progress{width: 0%;height: 100%;background-image: linear-gradient(to right, rgb(0,90,130),rgb(108,200,210));}這里的border-radius的單位一定是px,才能是兩頭圓的樣式,不能用%。然后進度條中的顏色漸變依然依靠linear-gradient。然后進度條本身也是div,出現(xiàn)加載的效果,是因為在定時器中不斷修改該div的width才出現(xiàn)的效果。
(所以進度條還是很容易實現(xiàn)的,之前以為會是很難的)
游戲客戶端主頁面
我將該頁面分為了三個區(qū)域:
首先涉及到初次進入客戶端出現(xiàn)的廣告效果
對于上方區(qū)域,從左往右說,play的按鈕本身肯定也是有素材在的,因為我沒找到所以就自己截了幾張。也就是說play是用a標(biāo)簽加background的形式實現(xiàn)的。然后列表欄(主頁、線、云頂…),這部分內(nèi)容就是所有網(wǎng)頁都會涉及的內(nèi)容了,有一些練習(xí)可以參考我之前的【文章】。那么這么多“按鈕”點擊后,會修改左下區(qū)域的內(nèi)容,去展示各自的信息,那么顯然只有Vue項目中才能做到了。除此以外,都是拿到素材,為其定位和設(shè)置樣式了。
然后上方區(qū)域還有一個就是鼠標(biāo)移動到頭像時,相應(yīng)內(nèi)容的顯現(xiàn)
對于右側(cè)好友區(qū)域,因為那些圖標(biāo)都需要素材,我又沒有找到的情況下,就去自己截了圖。對于好友區(qū)域上下方的各按鈕的觸發(fā)就沒有實現(xiàn)功能了(根據(jù)之前的功能實現(xiàn),其實這部分很簡單了)
然后右側(cè)區(qū)域還有一個就是好友列表下拉欄的實現(xiàn)
對于主頁內(nèi)容區(qū)域,除去素材的定位和元素樣式,重點就是輪播圖的實現(xiàn)
最后簡單說一下視頻的自動播放
初次進入客戶端的廣告
思路比較簡單:在主頁內(nèi)容區(qū)域,設(shè)置一個z-index優(yōu)先級很高的div,其寬高為當(dāng)前區(qū)域100%。再將其背景設(shè)為黑色并設(shè)置透明度,即可實現(xiàn)背景陰影效果。在其中再建一個可以點擊的圖片和關(guān)閉按鈕,其z-index高于底部div即可。
移入移出效果(mouseenter、mouseleave)
這個部分在通過之前打開服務(wù)器列表的功能實現(xiàn)后,也就很簡單了。只要鼠標(biāo)移入就打開,鼠標(biāo)移出就關(guān)閉,然后用transition設(shè)計效果即可。
打開的詳細(xì)內(nèi)容區(qū),我又把它分為三個區(qū)域。最上方區(qū)域就是用background,中間區(qū)域的頭像框和名字、下面區(qū)域的文字內(nèi)容,因為沒有具體的素材,再加上只有定位和樣式的設(shè)計,所以都是采用截圖的方式完成了。
好友列表的展開效果
這部分在我最開始構(gòu)思的時候覺得很復(fù)雜,后來想到了這個很簡單的方法。因為div元素是塊元素,它會獨自占據(jù)一行,那么根據(jù)這個特性,我們完全不需要設(shè)計什么,只需要當(dāng)我們點擊 最近游戲或者是好友列表,觸發(fā)事件,讓隱藏的內(nèi)容出現(xiàn),再像之前一樣實現(xiàn)三角形的樣式變化,該部分就完成了。(因為沒有具體素材信息,就直接采用截圖的方式,如果有素材,只需要將內(nèi)容都放在div里,也肯定可以實現(xiàn)該功能)
視頻的自動播放問題
在主頁頁面中,這個本來是個視頻,而且決定是讓它自動播放,但是經(jīng)過查閱資料發(fā)現(xiàn),只能使用這種方式:(autoplay和muted共同使用)
但是這樣使用,也就違背了自動播放視頻的初衷,因為它不會播放音樂。除此以外還有更嚴(yán)重的問題,就是在Chrome中,就算是這么設(shè)置也有時無法自動播放視頻,而這個所謂的有時,就是初次進入頁面時。當(dāng)瀏覽器緩存了視頻后,再次重新進入網(wǎng)頁就可以自動播放了。因此不知道有沒有什么解決方案。在這里我還實現(xiàn)了一個功能,就是當(dāng)點擊視頻的時候可以控制視頻播放和暫停。
playVideo(){ /*播放視頻*/if(this.play === false){video.play();this.play = true;}else{video.pause();this.play = false;}}輪播圖的實現(xiàn)
在具體看代碼前,先說一下這部分還存在未解決的問題:剛進入頁面的時候,第一次切換圖片沒有過渡效果,暫時不知道該如何解決。其實是有機會避免的,因為之前做過jQuery的輪播圖,但是到了這里用Vue之后,思路有點混亂,所以導(dǎo)致代碼部分出現(xiàn)了一些差錯,又不想進行過多的修改,所以導(dǎo)致為了掩蓋錯誤,去編寫更多代碼區(qū)彌補,不能很好的實現(xiàn)效果。所以相關(guān)思路可以參考我之前的文章【輪播圖練習(xí)三】(雖然代碼比較繁瑣,但至少實現(xiàn)了功能👇)
輪播圖的相關(guān)代碼:
<!--輪播圖--><div class="container"><!--圖片--><div id="list"><img src="./img/new-icon/pic1.jpg" alt="1"/><img src="./img/new-icon/pic2.jpg" alt="2"/><img src="./img/new-icon/pic3.jpg" alt="3"/><img src="./img/new-icon/pic4.jpg" alt="4"/><img src="./img/new-icon/pic5.jpg" alt="5"/></div></div><!--兩個箭頭--><a href="javascript:;" class="leftArrow" @click="left"></a><a href="javascript:;" class="rightArrow" @click="right"></a><!--輪播圖圓點--><div id="pointsDiv"><span index="1" class="on" @click="points($event)"></span><span index="2" @click="points($event)"></span><span index="3" @click="points($event)"></span><span index="4" @click="points($event)"></span><span index="5" @click="points($event)"></span></div> /*箭頭*/.leftArrow,.rightArrow{position: absolute;display: block;width: 2%;height: 7%;top: 30%;background-size: contain;background-repeat: no-repeat;z-index: 999;}.leftArrow{left: 5%;background-image: url("./img/game-icon/pre_nromal.png");}.rightArrow{right: 5%;background-image: url("./img/game-icon/next_normal.png");}.leftArrow:hover{background-image: url("./img/game-icon/pre_hover.png");}.leftArrow:active{background-image: url("./img/game-icon/pre_click.png");}.rightArrow:hover{background-image: url("./img/game-icon/next_hover.png");}.rightArrow:active{background-image: url("./img/game-icon/next_click.png");}/*圖片內(nèi)容區(qū)域*/.container{position: relative;width: 100%;height: 88%;top: 0;overflow: hidden;}/*包含所有圖片的<div>*/#list {width: 500%;height: 100%;position: absolute; /*絕對定位*/z-index: 1;transition-property: all;transition-duration: 0.5s;}/*所有的圖片<img>*/#list img {width: 20%;height: 120%;float: left;}/*包含所有圓點按鈕的<div>*/#pointsDiv {position: absolute;height: 10px;width: 100px;z-index: 2;bottom: 6%;left: 50%;transform: translateX(-50%);}/*所有的圓點<span>*/#pointsDiv span {cursor: pointer;float: left;border: 1px solid #A88230;width: 7px;height: 7px;border-radius: 50%;background: #333;margin-right: 5px;}/*第一個<span>*/#pointsDiv .on,#pointsDiv span:hover{background: #A88230;} <script type="text/javascript">new Vue({el: '#lolgame',data: {/*輪播圖的本質(zhì)是:一個很寬的div中存放著幾張圖片,每個圖片占據(jù)同樣的大小,*//*這個大小就是在主頁面區(qū)域能顯示的大小。那如果要切換到下一張圖,*//*其實就是修改left的值。即第一張圖就是left為0,第二張圖就是left為-100%*//*或者left是圖片的寬度(需要在設(shè)計時就考慮好)*//*因此num值的范圍不是1~5,而是0~4*/num: 1, /*記錄圖片位置,但是沒有考慮到數(shù)組的原因,num應(yīng)該為0的,出現(xiàn)了錯誤,導(dǎo)致代碼繁瑣*/first: true /*為自己錯誤買單*//*因為向右切換圖片后 num比正常下標(biāo)多1,所以需要標(biāo)記,即:first為true *//*所以只要first為true,那么向左切換圖片,下標(biāo)num就要-2,否則-1*/},mounted(){/*自動輪播*/this.intervalTime = setInterval(()=>{/*只要向右就將first設(shè)置為true*/this.first = true/*去調(diào)用right方法*/this.$options.methods.right.bind(this)();this.$options.methods.right();/*每5秒圖片切換1次*/},5000)},methods: {left(){ /*點擊左按鈕*/if(this.first === true){ /*只要圖片向右輪播*/this.num -= 2; /*那么下標(biāo)要-2*/this.first = false; /*向左輪播后,first為false*/}else{ /*正在向左輪播,只需要下標(biāo)-1*/this.num -= 1;}/*如果下標(biāo)減成負(fù)數(shù),那就意味著需要切換到最后一張圖片*/if(this.num === -1){this.num = 4}/*獲取到圖片列表,將圖片根據(jù)num的值,決定該顯示哪張圖片*/let $list = $('#list'); let per = -(this.num * 100);$list.css('left', per+'%');/*切換圖片后,需要修改下面圓標(biāo)點的樣式,需要對應(yīng)*/let index = this.num; /*獲取到當(dāng)前下標(biāo),此時num沒問題*/let preIndex; /*代表著前一個圖片的點*/if(index === 4){ /*如果向左切換到最后一張圖片,那么前一張圖片必然是第一張*/preIndex = 0}else{ /*其他情況,前一張圖片就是num + 1*/preIndex = this.num + 1}/*然后獲取所有的點*/let $points = $('#pointsDiv>span');/*將前一張圖片的點的樣式清除,給當(dāng)前的點添加樣式*/$points[preIndex].className = '';$points[index].className = 'on'},right(){ /*點擊右按鈕*/this.first = true /*只要向右切換,first就為true*//*之前提到num的范圍是0~4,但是這里向右輪播在設(shè)計時沒考慮到,出現(xiàn)了差錯*//*因為num初始值是1,向右輪播四張圖,每次num都+1了,顯然這里num為5才是最后一張圖*/if(this.num === 5){ /*如果向右切換到最后一張圖片*/this.num = 0; /*回到第一張圖*/}/*獲取到圖片列表,將圖片根據(jù)num的值,決定該顯示哪張圖片*/let $list = $('#list');let per = -(this.num * 100);$list.css('left', per+'%');this.num += 1;/*切換圖片后,需要修改下面圓標(biāo)點的樣式,需要對應(yīng)*/let index = this.num;let preIndex;if(index === 1){ /*如果此時index為1,也就是說上一張圖是最后一張圖*/preIndex = 4 }else{ /*否則上一張圖就會是num-2*/preIndex = this.num - 2}/*然后獲取所有的點*/let $points = $('#pointsDiv>span');/*將前一張圖片的點的樣式清除,給當(dāng)前的點添加樣式*/$points[preIndex].className = '';$points[index - 1].className = 'on';},points(e){ /*點擊圓點切換圖片*//*獲取span的index值*/let targetIndex = e.target.getAttribute('index')// 只有當(dāng)點擊的不是當(dāng)前頁的圓點時才翻頁// 這么實現(xiàn)是有bug的,因為左切換圖片會導(dǎo)致num錯亂,這時點擊圓點切換圖片就會出現(xiàn)問題// 但是我個人暫時就不想再從num為0重新設(shè)計了,因此就先這么辦了// 如果全程不點左箭頭,是不會出現(xiàn)bug的if(targetIndex != this.num) {// 先把上一個點的樣式取消this.num += 1;let index = this.num;let preIndex;if(index === 1){preIndex = 4}else{preIndex = this.num - 2}let $points = $('#pointsDiv>span');$points[preIndex].className = '';// 然后給這一個點增加樣式this.num = targetIndex - 1let $list = $('#list');let per = -(this.num * 100);$list.css('left', per+'%');this.num += 1;index = this.num;$points[index - 1].className = 'on';}}}}) </script>以上就是所有內(nèi)容。除此以外,在游戲客戶端主頁面的基礎(chǔ)上,再去實現(xiàn)其他標(biāo)簽的功能的話,涉及到更多英雄素材,比較費時,也不容易實現(xiàn),如果以后有機會再來嘗試實現(xiàn)吧。
總結(jié)
以上是生活随笔為你收集整理的【前端html页面练习】还原英雄联盟客户端的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 离线下载安装node插件
- 下一篇: websocket实现消息实时更新(亲测