his是一個關(guān)鍵字,表示執(zhí)行當(dāng)前函數(shù)的對象
function fn(){
console.log(this); //window
console.log(typeof this); //object
}
fn();
- 嚴(yán)格模式下,this指向undefiend
"use strict";
function fn(){
console.log(this); //undefined
}
fn();
文章目錄
0.官方文檔:
1.webpack概述:
2.webpack的基本使用:
3.在項目中安裝和配置 webpack:
4.配置自定義打包的自定義入口和出口:
4.配置自動打包功能:
5.配置生成預(yù)覽頁面功能:
6.配置自動打包相關(guān)參數(shù):
7.webpack 中的加載器:
8.loader加載器的基本使用:
9.Vue單文件組件:
10.webpack 打包發(fā)布:
11.以上所有配置 webpack.config.js 截圖
1.webpack概述:
webpack是一個流行的前端項目構(gòu)建工具(打包工具) ,可以解決當(dāng)前web開發(fā)中所面臨的困境
webpack提供了友好的模塊化支持,以及代碼壓縮混淆、處理js兼容問題、性能優(yōu)化等強大的功能,從而讓程序員把工作的重心放到具體的功能實現(xiàn)上,提高了開發(fā)效率和項目的可維護性
2.webpack的基本使用:
2.1:打開終端運行命令 npm init -y 初始化包管理配置文件 package.json
2.2:新建 src 源文件目錄(里面放程序員自己寫的代碼比如 html css js images …)
2.3:如果需要引入 jquery 庫 終端運行以下命令npm install jquery -S 安裝 jquery
自己在src文件夾中創(chuàng)建 index.js 引入下載的jquery包import $ from 'jquery'
3.在項目中安裝和配置 webpack:
3.1:終端運行 npm install webpack-cli -D 命令,安裝webpack相關(guān)的包
這里要注意一個問題 : package.json 和 package-lock.json 文件里的名字默認(rèn)為 “name”=“webpack”,在配置 webpack-cli 之前要把name 改成 其他名字 比如 “name”=“webpack_” 不然的話為出現(xiàn)無法安裝的問題
具體可點擊這里 Webpack依賴包安裝問題解決方案
3.2:在項目根目錄中 ,創(chuàng)建名為 webpack.config.js 的 webpack 配置文件
3.3:在 webpack.config.js 中,初始化一下基本配置
建議選擇 development (打包速度快,體積大),項目上線是才改成 production (如果選擇production會進行代碼的壓縮和混淆,打包速度慢,體積小)
3.4:在package.json中的 script節(jié)點 新增一個dev腳本 值為 webpack ,就可以實現(xiàn)打包功能
在終端運行命令:npm run dev
就可以打包 默認(rèn)打包成main.js在 dist文件夾中
在src自己新建的index.html 中引入打包后的 js
屬性描述符就是一個屬性除了屬性名與屬性值之外的其他相關(guān)信息
通過Object.getOwnPropertyDescriptor(對象, 屬性名)
可以得到一個對象的某個屬性的屬性描述符
let obj = { a: 1 } console.log(Object.getOwnPropertyDescriptor(obj, 'a')); // { // value: 1, // writable: true, // enumerable: true, // configurable: true // }
通過Object.getOwnPropertyDescriptors(對象)
可以得到某個對象的所有屬性描述符
let obj = { a: 1, b: 2 } console.log(Object.getOwnPropertyDescriptors(obj)); // { // a: { // value: 1, // writable: true, // enumerable: true, // configurable: true // } // b: { // value: 2, // writable: true, // enumerable: true, // configurable: true // } // }
接下來,說一說每一個屬性描述符的作用
不多逼逼
當(dāng)我們設(shè)置configurable為false以后,再去修改屬性描述符的話,會報錯
let obj = { a: 1, b: 2 } Object.defineProperty(obj, 'a', { value: 'a', configurable: false }) Object.defineProperty(obj, 'a', { value: 'a', configurable: true }) // Uncaught TypeError: Cannot redefine property: a // at Function.defineProperty (<anonymous>)
當(dāng)設(shè)置一個屬性的enumerable為false時,該屬性不可被forin循環(huán)
但是不影響forof循環(huán),因為forof循環(huán)看有沒有Symbol(Symbol.iterator)
forin循環(huán)的是屬性名,forof循環(huán)的是屬性值
不用看時間,你沒有穿越,現(xiàn)在是 2020 年,不是 2000 年。這復(fù)古的字體設(shè)計和這帶有年代感的落日背景,以及悠揚壯闊的背景音樂,甚至讓我以為是在看二十年前新年晚會的演出視頻。
△ 視頻鏈接:https://v.youku.com/v_show/id_XNDYzNTE2MzgxNg==.html
不得了,不得了,恒大足球場的宣傳視頻甚至登上了央視的廣告舞臺,展示給了全國觀眾,壕氣十足,花開富貴,這絢爛的煙花背景,讓我瞬間夢回三十年前。
建筑不僅外表華麗,其實文化內(nèi)涵還很深厚,與中老年表情包冥冥之中有了一個巧妙的對應(yīng),蘊含著給你帶來好運,祝你平安健康。
據(jù)網(wǎng)友考據(jù),設(shè)計理念可能來自于一盆多肉,為了更加貼近人民群眾的生活,讓人們時時感受到自然的美妙。
還有網(wǎng)友幻想出最終建設(shè)完成時的終極形態(tài),積極對建筑進行了自己的解讀和創(chuàng)作,看這廣泛的聯(lián)合角色設(shè)計,佛祖、紅孩兒;這跨越多個時代的風(fēng)格雜糅,上個世紀(jì)的吉祥如意、這個世紀(jì)的游戲建模;涵蓋多個領(lǐng)域的蓮花主題,植物、彩燈,應(yīng)有盡有,真是妙??!
什么?你覺得不好看嗎?這可是恒大總裁許家印從 9 種蓮花寶座設(shè)計方案中精挑細(xì)選出來的一個!九種不同的蓮花設(shè)計方案,深淺不同的粉紅色,看不出有多大不同的開合程度,微微不一樣的花瓣設(shè)計,供你瞪大雙眼選擇。
你問:可以阻止這個色彩絢麗的建筑修建起來么?來晚了,蓮花寶座已經(jīng)于 4 月 16 日開始修建,屆時會成為世界規(guī)模最大的頂尖專業(yè)足球場。開心一點,說不定以后能在中國看世界杯了呢。
既然是世界規(guī)模最大的頂尖足球場!為什么不修好看一點?這什么設(shè)計師,這種紅配綠,亮瞎人眼的設(shè)計是哪個沙雕公司設(shè)計的?許老板這么有錢,怎么不請好一點的設(shè)計師呢。廣州這么時尚的城市配上這樣的土味建筑,真是令人頭大。其實,你可能罵錯人了。背后的設(shè)計公司可是 Gensler,現(xiàn)在世界上數(shù)一數(shù)二的的設(shè)計團隊。這不是變魔術(shù),設(shè)計出上面土味十足的建筑和下面高級感撲面而來的建筑的就是一個團隊。
上海中心大廈(右一),憑借其獨特的造型和樓高,榮獲諸多大獎,成為上海地標(biāo)性的建筑之一。
還有菲律賓金融中心大廈,與周圍的建筑對比起來,科技感和現(xiàn)代感十足,在 CBD 群中獨占鰲頭。
又或者是在波士頓起到樞紐作用的綜合體建筑設(shè)計,一眼望去稱霸整個地區(qū)。
這怎么看,都不像是一個團隊設(shè)計出來的作品。蓮花球場和高級感相關(guān)在哪里?這不是隨隨便便一個設(shè)計師都可以設(shè)計出來的么?其實,這也不是許老板第一次這么偏愛蓮花了,看看?;◢u項目就知道了,網(wǎng)友調(diào)侃說到,果然設(shè)計師還是敗給了金錢。
不過同樣是以蓮花為設(shè)計元素,印度的蓮花寺怎么看起來就這么高端優(yōu)雅呢?與蓮花球場「土味建筑」不同的是,蓮花寺廣受好評,被稱為新德里的「悉尼歌劇院」。
類似蓮花球場這樣的案例在中國還有很多。之前被評為 2017 年中國最丑陋的十大建筑之一的廣州圓大廈,由意大利米蘭設(shè)計師 Joseph di Pasquale 設(shè)計,他在采訪中說到:「中國改變了他,讓他知道了文化如何融于建筑,如何更好地滿足客戶的欲望。」其實建筑的寓意「雙環(huán)玉璧」是很好的,但是最終的效果不盡人意,建筑類似于黃金的外表顏色,被網(wǎng)友們吐槽,稱其為「土豪圓」。
不過設(shè)計這個事情,有時候也很難去用單純的美丑判別。例如設(shè)計出臺北 101 大廈的李祖原老師,在同年設(shè)計出的沈陽方圓大廈,是參考銅錢的形狀設(shè)計而成。在 2000 年威尼斯世界建筑設(shè)計展覽會上被稱贊為是「世界上最具創(chuàng)意性和革命性的完美建筑」,但在 2012 年卻被 CNN 旗下的生活旅游網(wǎng)評選為全球最丑的十大建筑之一。
你以為這就結(jié)束了嗎?別走,奇葩建筑還有很多,中國各個省都互不相讓。首先我們從南看起,海南三亞的「美麗之冠」,就是后面那些像樹一樣的建筑,一模一樣的樓不知道為什么要修建九個。
往北走,我們來到了官方宣傳視頻里寫到的「不來萬家麗,枉來中國行」,之中的世界最大建筑「長沙萬家麗」。這棟同樣金碧輝煌、中西結(jié)合的建筑讓你深刻體會到一句話「有錢就是可以為所欲為」。不論是美是丑是否合適,只要是自己喜歡的元素,通通都堆砌在一棟建筑里。
接著我們來到了山東的文成城堡,沈騰的《西虹市首富》取景地,看看這個豪華程度,一晃神還以為自己來到了歐洲。
最后我們來到河北,學(xué)習(xí)魔法不需要出國,直接來河北美術(shù)學(xué)院,一個被戲稱為「霍格沃茨華北分?!沟拿佬g(shù)帝國,由于其仿照魔法學(xué)院進行的設(shè)計,在中國眾多美院中獨樹一幟。
以上這些奇葩建筑的盤點,均來自于 B 站 up 主史里芬 Schlieffen,一個被長沙萬家麗老板黃總盛情邀請再次體驗萬家麗的男人。盤點中國奇葩建筑,現(xiàn)代青年當(dāng)仁不讓。想要了解中國建筑底層設(shè)計的朋友,可以前去品鑒和觀賞,不要怪我用丑陋和土味蒙蔽了你們的雙眼。押韻的解說詞,第一視角的全方位建筑講解,你值得擁有。
主頁鏈接:https://space.bilibili.com/323733137/
這樣的建筑作品很新鮮但是確實不美觀。且不說中國其實有很多好的設(shè)計師,為什么和國外知名設(shè)計團隊合作,做出來的作品依舊差強人意呢?難不成是我們的審美水平真的已經(jīng)淪落成這個地步了?如果哪天全民都覺得這樣的建筑是美的,都欣賞這樣的建筑,那我們整個社會才算是陷入了「惡趣味審美」之中,就真正完蛋了。標(biāo)榜著以「蓮花綻放」這一美好寓意為核心的蓮花球場設(shè)計,何嘗不是披著虛偽外衣的土味建筑設(shè)計呢?美能夠讓人感到幸福,反過來,丑則使人感到不適。
對于蓮花寶座外形的足球場設(shè)計,我想開了,畢竟我不是亞洲第五富,眾位設(shè)計師,你們是怎樣看待的呢?
文章來源:優(yōu)設(shè)
feed 單詞釋義:v. 喂養(yǎng);進食;為……提供充足的食物;施肥;為(某人)提供(信息、主意等);
n. 飼料;飼養(yǎng);(尤指給動物或嬰兒)喂食;進食;(計算機的)訂閱源
形象來講,如今新浪微博、微信朋友圈、抖音、今日頭條、小紅書、Facebook、QQ 空間等等內(nèi)容平臺每時每刻都在不斷投喂給我們賴以維系健康生活(廢柴生活)的精神食糧——信息內(nèi)容。而這些信息組合起來的格式便是 feed。
1. Feed
feed 是一種信息格式,平臺通過它將資訊傳遞給用戶。feed 是信息聚合的最小單元,每一條狀態(tài)或者消息都是 Feed,比如朋友圈中的一個動態(tài)就是一個Feed,微博中的一條微博就是一個 Feed。
2. Feed流
feed 流即持續(xù)更新并呈現(xiàn)給用戶內(nèi)容的信息流。每個人的朋友圈,微博關(guān)注頁,頭條新聞等等都是一個 Feed 流。
Feed 源于早期的 RSS(Really Simple Syndication )
RSS(簡易信息聚合):將用戶主動訂閱的若干消息源組合在一起形成內(nèi)容(aggregator),幫助用戶持續(xù)地獲取的訂閱源內(nèi)容。對用戶而言,聚合器是專門用來訂閱網(wǎng)站的軟件,一般亦稱為 RSS 閱讀器、feed 閱讀器、新聞閱讀器等。用戶選擇訂閱多個訂閱源,網(wǎng)站提供 feed 網(wǎng)址 ,用戶將 feed 網(wǎng)址登記到聚合器里,在聚合器里形成聚合頁,用戶便能持續(xù)地獲取的訂閱源內(nèi)容。
在早期的 Web 時代,訂閱源一般是新聞網(wǎng)站以及博客。用戶主動訂閱感興趣的多個訂閱源,訂閱器幫用戶及時更新訂閱源信息,然后按照 timeline 時間順序展示出來。這樣,用戶可以通過訂閱器獲取即時信息,而不用每天都檢查各個訂閱源是否有更新。
轉(zhuǎn)折出現(xiàn)在 2006 年,F(xiàn)acebook 宣布了一項新的首頁形式「News Feed」,這一形式打破了傳統(tǒng) RSS 的訂閱方式。News Feed 可以看做一個新型聚合器,訂閱源不僅僅是某個網(wǎng)址、某個新聞網(wǎng)站或者某個內(nèi)容,而是生產(chǎn)內(nèi)容的人或者團體,而內(nèi)容即是好友或關(guān)注對象的動態(tài)(發(fā)布的內(nèi)容以及其他的社交行為)。News Feed 的出現(xiàn)使得 RSS 被迫淡出歷史舞臺。News Feed 發(fā)展至今已經(jīng)拓展出多種多樣的模式和呈現(xiàn)方式。
推模式:每當(dāng)用戶發(fā)帖,對所有粉絲推送一條該用戶的動態(tài)消息記錄。需要考慮的是如果一個粉絲量級非常大的用戶(大 V),發(fā)布一條動態(tài)那么需要在每個粉絲頁推送一條動態(tài),多個大 V 級別用戶同時發(fā)帖對數(shù)據(jù)的存儲負(fù)荷是非常大的。
拉模式:每當(dāng)請求好友動態(tài),拉取用戶所有關(guān)注者的最近動態(tài),然后匯總排序。如果用戶同時關(guān)注非常多的用戶,那么查詢這類型的用戶的關(guān)注列表也是很大的數(shù)據(jù)成本。
推拉模式:在線推,離線拉;定時推,離線拉。
除了關(guān)注 feed 流的主要模式之外,feed 流的排序方式也值得一提:
Timeline:按發(fā)布的時間順序排序,先發(fā)布的先看到,后發(fā)布的排列在最頂端,類似于微信朋友圈等。這也是一種最常見的形式。產(chǎn)品如果選擇 Timeline 類型,那么就是認(rèn)為 feed 流中的 feed 不多,但是每個 feed 都很重要,都需要用戶看到。
Rank:按某個非時間的因子排序,一般是按照用戶的喜好度排序,用戶最喜歡的排在最前面,次喜歡的排在后面。這種一般假定用戶可能看到的 Feed 非常多,而用戶花費在這里的時間有限,那么就為用戶選擇出用戶最想看的 Top N 結(jié)果,場景的應(yīng)用場景有微博、頭條新聞推薦類、商品、視頻推薦等。
目前 feed 流的主流排序方式不再嚴(yán)格按照 timeline,而是廣泛使用智能 feed 排序。
智能排序基于趨勢 trending、熱門 hot、用戶生產(chǎn) UGC 、編輯推薦 PGC、相似 Similarity 等等因素綜合考慮,隨著技術(shù)的進步,智能算法將會更加懂得用戶的喜好。新的 feed 流不再需要用戶主動訂閱或者搜索,只要監(jiān)測我們的瀏覽時長、點贊分享等動作,或者建立用戶畫像類別,就可以主動推薦我們感興趣的內(nèi)容。它對我們了如指掌,給我們想了解的,讓我們不停刷新沉溺于其中。就現(xiàn)在 feed 流中的廣告,女性用戶對化妝品的喜好,男性用戶對車的偏愛,臨時借錢的窘迫,這些暖廣告已經(jīng)不再像牛皮癬一樣惹人討厭,甚至變成了一顆我們愿意吃下的安利。
可以有以下大致分類:
feed 作為信息聚合的最小單元,每一個 feed 都會具備相應(yīng)的內(nèi)容。其中包括發(fā)布的時間、發(fā)布者、文字內(nèi)容、圖片內(nèi)容,還包含點贊、轉(zhuǎn)發(fā)、評論、關(guān)注等操作、根據(jù)應(yīng)用場景、業(yè)務(wù)目標(biāo)不同,其表現(xiàn)方式也大有不同,任何表現(xiàn)形式都應(yīng)該是為了更好地呈現(xiàn)功能及內(nèi)容。
新聞資訊類產(chǎn)品和社交互動類產(chǎn)品 feed 元素大體相同,區(qū)別在于新聞資訊類產(chǎn)品通常著重展現(xiàn)新聞內(nèi)容,標(biāo)題,簡介,匹配的圖片等,而發(fā)布時間和發(fā)布作者等會在單個 feed 的底部出現(xiàn)。在圖文兼?zhèn)涞呐虐娌季种?,左文右圖適合文字內(nèi)容類比如文章或者知乎、豆瓣等長答案評論等,圖片是輔助信息支撐文字內(nèi)容。左圖右文圖片更加吸引人的注意通常出現(xiàn)在商品信息比如什么值得買。
社交互動類產(chǎn)品,其最終目的是發(fā)現(xiàn)和拓展社交關(guān)系,融入相應(yīng)的社交圈。而這時候社交拓展的基本單位人或者團體發(fā)揮著至關(guān)重要的作用。所以我們可以發(fā)現(xiàn),通常的社交互動軟件都會將發(fā)布者頭像放在上部展示的位置,也會在底部突出點贊,評論,分享等互動操作。
視頻直播類產(chǎn)品與前兩者相異,頁面的大部分空間留給視頻內(nèi)容的展示,一般一屏只承載一個 feed 信息單元,內(nèi)容等提示元素在左側(cè)呈現(xiàn),除回復(fù)評論等操作元素列在右側(cè)。
feed 中各元素的位置關(guān)系、所占比例與產(chǎn)品自身定位密切相關(guān)。如微博作為泛社交應(yīng)用產(chǎn)品,社交關(guān)系主要建立在內(nèi)容上,社交關(guān)系質(zhì)量較弱,多為單向傳播,注重的是傳播的速度和內(nèi)容公開。所以其 feed 的呈現(xiàn)方式發(fā)布者與發(fā)布內(nèi)容不做明顯的設(shè)計排布區(qū)分。以卡片間隔的形式在 feed 與 feed 之間做區(qū)隔。評論頁面在下一層級。
微信是作為一個社交工具,社交關(guān)系質(zhì)量較強,多為雙向關(guān)系,注重的是私人內(nèi)容的交流和互動,信息的傳播速度不快,但受眾信息消化率很高。所以將發(fā)布者頭像與發(fā)布內(nèi)容做出較明顯區(qū)分,feed 與 feed 之間因為已經(jīng)有了頭像元素這一明顯區(qū)別要素,僅用分割線做區(qū)隔。且注重評論區(qū)域的互動與展示。
無論怎樣的設(shè)計布局方式,遵循的核心思想始終是根據(jù)場景需求、業(yè)務(wù)目標(biāo)去發(fā)展深化設(shè)計方案。每一個設(shè)計點都要有足夠的支撐,多問問自己為什么這么設(shè)計,解決了用戶什么樣的問題?還有沒有更好的替代方案?而不是這樣設(shè)計是不是新穎,出奇制勝。
文章來源:優(yōu)設(shè) 作者:Nicole
性能優(yōu)化(網(wǎng)絡(luò)方向)
web應(yīng)用無非是兩臺主機之間互相傳輸數(shù)據(jù)包的一個過程; 如何減少傳輸過程的耗時就是網(wǎng)絡(luò)方向優(yōu)化的重點, 優(yōu)化出發(fā)點從第一篇文章中說起
DNS解析過程的優(yōu)化
當(dāng)瀏覽器從第三方服務(wù)跨域請求資源的時候,在瀏覽器發(fā)起請求之前,這個第三方的跨域域名需要被解析為一個IP地址,這個過程就是DNS解析;
DNS緩存可以用來減少這個過程的耗時,DNS解析可能會增加請求的延遲,對于那些需要請求許多第三方的資源的網(wǎng)站而言,DNS解析的耗時延遲可能會大大降低網(wǎng)頁加載性能。
dns-prefetch
當(dāng)站點引用跨域域上的資源時,都應(yīng)在<head>元素中放置dns-prefetch提示,但是要記住一些注意事項。首先,dns-prefetch僅對跨域域上的DNS查找有效,因此請避免將其用于您當(dāng)前訪問的站點
<link rel="dns-prefetch" >
preconnect
由于dns-prefetch僅執(zhí)行DNS查找,但preconnect會建立與服務(wù)器的連接。如果站點是通過HTTPS服務(wù)的,則此過程包括DNS解析,建立TCP連接以及執(zhí)行TLS握手。將兩者結(jié)合起來可提供機會,進一步減少跨源請求的感知延遲
<!-- 注意順序, precontent和dns-prefetch的兼容性 -->
<link rel="preconnect" crossorigin>
<link rel="dns-prefetch" >
TCP傳輸階段優(yōu)化
這個前端方面好像能做的有限, 我們都知道 http協(xié)議 是基于 tcp的;
升級http協(xié)議版本可以考慮下, 比如把 http/1.0 -> http/1.1 -> http/2;
這個需要我們在應(yīng)用服務(wù)器上配置(nginx, Apache等), 不做概述了, 另外還需要客戶端和服務(wù)器都支持哦, 目前還沒開發(fā)出穩(wěn)定版本,好多只支持https,不過也不遠(yuǎn)了...
http2 的優(yōu)勢
# 1.多路復(fù)用: 同一個tcp連接傳輸多個資源
這樣可以突破統(tǒng)一域名下只允許有限個tcp同時連接,
這樣http1.1所做的減少請求數(shù)優(yōu)化就沒有太大必要了
如多張小圖合成一張大圖(雪碧圖),合并js和css文件
# 2.報文頭壓縮和二進制編碼: 減少傳輸體積
http1 中第一次請求有完整的http報文頭部,第二次請求的也是;
http2 中第一次請求有完整的http報文頭部,第二次請求只會攜帶 path 字段;
這樣就大大減少了發(fā)送的量。這個的實現(xiàn)要求客戶端和服務(wù)同時維護一個報文頭表。
# 3.Server Push
http2可以讓服務(wù)先把其它很可能客戶端會請求的資源(比如圖片)先push發(fā)給你,
不用等到請求的時候再發(fā)送,這樣可以提高頁面整體的加載速度
但目前支持性不太好...emm...
總的來說, 在 c 端業(yè)務(wù)下不會太普及, 畢竟需要軟件支持才行...
http 請求響應(yīng)階段優(yōu)化
為了讓數(shù)據(jù)包傳輸?shù)母? 我們可以從兩個方面入手: 請求的數(shù)據(jù)包大小(服務(wù)器), 請求數(shù)據(jù)包的頻率(客戶端)
減少請求文件的大小
請求文件對應(yīng)的是我們項目完成后,打包所指的靜態(tài)資源文件(會被部署到服務(wù)器), 文件越小, 傳輸?shù)臄?shù)據(jù)包也會相對較小, 講道理也會更快到達(dá)客戶端
how to reduce a package size?
目前我們都會使用打包工具了(比如webpack, rollup, glup 等), 如何使用工具來減小包的體積呢? 這邊建議您去官網(wǎng)文檔呢...當(dāng)然這里列舉一下常用的手段(webpack 的), 但是注意要插件版本更新哦
JS文件壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
plugins: [
new UglifyJsPlugin({
// 允許并發(fā)
parallel: true,
// 開啟緩存
cache: true,
compress: {
// 刪除所有的console語句
drop_console: true,
// 把使用多次的靜態(tài)值自動定義為變量
reduce_vars: true,
},
output: {
// 不保留注釋
comment: false,
// 使輸出的代碼盡可能緊湊
beautify: false
}
})
]
}
CSS 文件壓縮
// optimize-css-assets-webpack-plugin
plugins: [
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
}),
];
html 文件壓縮
// html-webpack-plugin
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.html'),
filename: 'index.html',
chunks: ['index'],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false,
},
}),
];
source map 文件關(guān)閉
tree shaking
1.代碼不會被執(zhí)行,不可到達(dá),比如 if(false){// 這里邊的代碼}
2.代碼執(zhí)行的結(jié)果不會被用到
3.代碼只會影響死變量(只寫不讀)
4.方法不能有副作用
// 原理相關(guān): 以后在研究
利用 ES6 模塊的特點:
只能作為模塊頂層的語句出現(xiàn)
import 的模塊名只能是字符串常量
import binding 是 immutable 的
代碼擦除: uglify 階段刪除無用代碼
scope hoisting(作用域提升)
分析出模塊之間的依賴關(guān)系,盡可能的把打散的模塊合并到一個函數(shù)中去,但前提是不能造成代碼冗余
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
module.exports = {
resolve: {
// 針對 Npm 中的第三方模塊優(yōu)先采用 jsnext:main 中指向的 ES6 模塊化語法的文件
mainFields: ['jsnext:main', 'browser', 'main']
},
plugins: [
// 開啟 Scope Hoisting
new ModuleConcatenationPlugin(),
],
};
項目中使用按需加載,懶加載(路由,組件級)
const router = new VueRouter({
routes: [
{ path: '/foo', component: () => import(/* webpackChunkName: "foo" */ './Foo.vue') }
{ path: '/bar', component: () => import(/* webpackChunkName: "bar" */ './Bar.vue') }
]
})
開啟 gizp 壓縮
有時候啟用也會消耗服務(wù)器性能, 看情況使用吧
暫時先提這么些吧...后續(xù)想到了再加
減少請求頻率
因為同一域名下 tcp 連接數(shù)的限制導(dǎo)致過多的請求會排隊阻塞, 所以我們需要盡量控制請求的數(shù)量和頻率
常見措施
將靜態(tài)資源的內(nèi)聯(lián)到HTML中
這樣這些資源無需從服務(wù)器獲取, 但可能影響到渲染進程...
<!-- 1.小圖片內(nèi)聯(lián) base64 (url-loader) -->
<!-- 2.css內(nèi)聯(lián) -->
<!-- 3.js內(nèi)聯(lián) -->
<script>
${require('raw-loader!babel-loader!./node_modules/lib-flexible/flexible.js')}
</script>
利用各級緩存(下一篇存儲方面介紹)
通常都是在服務(wù)端做相關(guān)配置, 但你要知道
我們可以利用http緩存(瀏覽器端)來減少和攔截二次請求, 當(dāng)然一般都是在服務(wù)端設(shè)置的;
服務(wù)器端也可以設(shè)置緩存(redis等), 減少數(shù)據(jù)查詢的時間同樣可以縮短整個請求時間
利用本地存儲
我們可以將常用不變的信息存在本地(cookie,storage API 等);
判斷存在就不去請求相關(guān)的接口, 或者定期去請求也是可以的
花錢買 CDN 加速
CDN 又叫內(nèi)容分發(fā)網(wǎng)絡(luò),通過把資源部署到世界各地,用戶在訪問時按照就近原則從離用戶最近的服務(wù)器獲取資源,從而加速資源的獲取速度。 CDN 其實是通過優(yōu)化物理鏈路層傳輸過程中的網(wǎng)速有限、丟包等問題來提升網(wǎng)速的...
購買 cdn 服務(wù)器;
然后把網(wǎng)頁的靜態(tài)資源上傳到 CDN 服務(wù)上去,
在請求這些靜態(tài)資源的時候需要通過 CDN 服務(wù)提供的 URL 地址去訪問;
# 注意, cdn 緩存導(dǎo)致的新版本發(fā)布后不生效的問題
所以打包的時候常在文件后面加上 hash 值
然后在 HTML 文件中的資源引入地址也需要換成 CDN 服務(wù)提供的地址
/alicdn/xx12dsa311.js
# 利用不同域名的 cdn 去存放資源, (tcp連接限制)
webpack 構(gòu)建時添加 cdn
// 靜態(tài)資源的導(dǎo)入 URL 需要變成指向 CDN 服務(wù)的絕對路徑的 URL 而不是相對于 HTML 文件的 URL。
// 靜態(tài)資源的文件名稱需要帶上有文件內(nèi)容算出來的 Hash 值,以防止被緩存。
// 不同類型的資源放到不同域名的 CDN 服務(wù)上去,以防止資源的并行加載被阻塞。
module.exports = {
// 省略 entry 配置...
output: {
// 給輸出的 JavaScript 文件名稱加上 Hash 值
filename: '[name]_[chunkhash:8].js',
path: path.resolve(__dirname, './dist'),
// 指定存放 JavaScript 文件的 CDN 目錄 URL
publicPath: '//js.cdn.com/id/',
},
module: {
rules: [
{
// 增加對 CSS 文件的支持
test: /\.css$/,
// 提取出 Chunk 中的 CSS 代碼到單獨的文件中
use: ExtractTextPlugin.extract({
// 壓縮 CSS 代碼
use: ['css-loader?minimize'],
// 指定存放 CSS 中導(dǎo)入的資源(例如圖片)的 CDN 目錄 URL
publicPath: '//img.cdn.com/id/'
}),
},
{
// 增加對 PNG 文件的支持
test: /\.png$/,
// 給輸出的 PNG 文件名稱加上 Hash 值
use: ['file-loader?name=[name]_[hash:8].[ext]'],
},
// 省略其它 Loader 配置...
]
},
plugins: [
// 使用 WebPlugin 自動生成 HTML
new WebPlugin({
// HTML 模版文件所在的文件路徑
template: './template.html',
// 輸出的 HTML 的文件名稱
filename: 'index.html',
// 指定存放 CSS 文件的 CDN 目錄 URL
stylePublicPath: '//css.cdn.com/id/',
}),
new ExtractTextPlugin({
// 給輸出的 CSS 文件名稱加上 Hash 值
filename: `[name]_[contenthash:8].css`,
}),
// 省略代碼壓縮插件配置...
],
};
/*
以上代碼中最核心的部分是通過 publicPath 參數(shù)設(shè)置存放靜態(tài)資源的 CDN 目錄 URL,
為了讓不同類型的資源輸出到不同的 CDN,需要分別在:
output.publicPath 中設(shè)置 JavaScript 的地址。
css-loader.publicPath 中設(shè)置被 CSS 導(dǎo)入的資源的的地址。
WebPlugin.stylePublicPath 中設(shè)置 CSS 文件的地址。
設(shè)置好 publicPath 后,WebPlugin 在生成 HTML 文件和 css-loader 轉(zhuǎn)換 CSS 代碼時,會考慮到配置中的 publicPath,用對應(yīng)的線上地址替換原來的相對地址。
*/
參考
DNS MDN]
webpack 文檔
深入淺出 Webpack
Scope Hoisting
IOS下的webview頁面,內(nèi)嵌iframe元素,將其樣式指定為寬高100%:
.iframe { width: 100%; height: 100%;
}
在安卓下運行均無問題,但是在IOS下會出現(xiàn)異常。
具體表現(xiàn)為iframe頁面內(nèi)的子元素一旦超出原先的邊界,只要能影響到html元素的寬高,就會自動撐開iframe,即使html元素設(shè)置了overflow:hidden
也沒用。
比如一個body元素下的彈層需要從下往上滑動進場,這個彈層的位置就會導(dǎo)致html高度的變化,因此頁面底部的tabbar就會在彈層運動期間先消失再出現(xiàn)。
解決方法就是使用具體的寬高數(shù)值鎖定iframe元素:
function onLoadIFrame (index) { // 修復(fù)IOS下輪播圖初始化瞬間會讓iframe寬度自行擴大問題 if (this.ENV.isIOS) { const iframe = this.$el.querySelector('#iframe' + index)
iframe.style.width = iframe.clientWidth + 'px' iframe.style.height = iframe.clientHeight + 'px' }
}
在了解了javascript的語言基礎(chǔ)和特性后
javascript真正大放光彩的地方來了——這就是javascript DOM
Javascript DOM
DOM(Document Object Model),文檔對象模型。
是W3C組織推薦的處理可擴展標(biāo)記語言(HTML或者XML)的標(biāo)準(zhǔn)編程接口;W3C已經(jīng)定義了一系列DOM接口,通過這些DOM接口可以改變網(wǎng)頁的內(nèi)容、結(jié)構(gòu)和樣式。
簡單的說就是一套操作文檔內(nèi)容的方法。
需要注意的是,我們需要把DOM當(dāng)作一個整體,不能分割看待,即DOM(文檔對象模型)是一套操作文檔內(nèi)容的方法。
DOM把以上內(nèi)容看作都是對象
<!DOCTYPE html> <html> <head> <title>Shopping list</title> <meta charset="utf-8"> </head> <body> <h1>What to buy</h1> <p id="buy" title="a gentle reminder">Don't forget to buy this stuff</p> <ul id="purchases"> <li>A tin od beans</li> <li>Cheese</li> <li>Milk</li> </ul> </body> </html>
1、獲取DOM四種基本方法
1、getElementById()
2、getElementsByTagname()
3、getAttribute()
4、setAttribute()
常用的兩種解析:
1. getElementById():
參數(shù):元素的ID值。 (元素節(jié)點簡稱元素)
返回值:一個有指定ID的元素對象(元素是對象)
注:這個方法是與document對象相關(guān)聯(lián),只能由document對象調(diào)用。
用法:document.getElementById(Id)
例:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="time">2020-04-16</div> <script> // 1. 因為我們文檔頁面從上往下加載,所以先得有標(biāo)簽 所以我們script寫到標(biāo)簽的下面 // 2. get 獲得 element 元素 by 通過 駝峰命名法 // 3. 參數(shù) id是大小寫敏感的字符串 // 4. 返回的是一個元素對象 var timer = document.getElementById('time'); console.log(timer); console.log(typeof timer); // 5. console.dir 打印我們返回的元素對象 更好的查看里面的屬性和方法 console.dir(timer); </script> </body> </html>
看一下控制臺打印的是什么
可以看到 console.log(timer)打印出來的是整個div標(biāo)簽
timer類型是個對象
2. getElementsByTagName():
參數(shù):元素名
返回值:一個對象數(shù)組。這個數(shù)組里每個元素都是對象,每個對象分別對應(yīng)著文檔里給定標(biāo)簽的一個元素。
注:這個方法可和一般元素關(guān)聯(lián)。這個方法允許我們把通配符當(dāng)作它的參數(shù),返回在某份html文檔里總共有多少個元素節(jié)點。
用法:element.getElementsByTagName(TagName)
例:
var items=document.getElementsByTagName("li");
items.length;//3
document.getElementsByTagName(“*”);//12
2、事件基礎(chǔ)
3.1 事件概述
JavaScript使我們有能力創(chuàng)建動態(tài)頁面,而事件是可以被JavaScript偵測到的行為。
簡單理解:觸發(fā)——>響應(yīng)機制
網(wǎng)頁中每個元素都可以產(chǎn)生某些可以觸發(fā)JavaScript的事件,例如,我們可以在用戶點擊某按鈕產(chǎn)生一個事件,然后去執(zhí)行某些操作
3.2 事件三要素
事件源 、事件類型、事件處理程序,我們也稱為事件三要素
(1) 事件源 事件被觸發(fā)的對象 誰
(2) 事件類型 如何觸發(fā) 什么事件 比如鼠標(biāo)點擊(onclick) 還是鼠標(biāo)經(jīng)過 還是鍵盤按下
(3) 事件處理程序 通過一個函數(shù)賦值的方式 完成
代碼實例
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <button id="btn">唐伯虎</button> <script> // 點擊一個按鈕,彈出對話框 // 1. 事件是有三部分組成 事件源 事件類型 事件處理程序 我們也稱為事件三要素 //(1) 事件源 事件被觸發(fā)的對象 誰 按鈕 var btn = document.getElementById('btn'); //(2) 事件類型 如何觸發(fā) 什么事件 比如鼠標(biāo)點擊(onclick) 還是鼠標(biāo)經(jīng)過 還是鍵盤按下 //(3) 事件處理程序 通過一個函數(shù)賦值的方式 完成 btn.onclick = function() { alert('點秋香'); } </script> </body> </html>
運行結(jié)果
1、獲取事件源
2、注冊事件(綁定事件)
3、添加事件處理程序(采取函數(shù)賦值形式)
代碼實戰(zhàn)
-
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div>123</div> <script> // 執(zhí)行事件步驟 // 點擊div 控制臺輸出 我被選中了 // 1. 獲取事件源 var div = document.querySelector('div'); // 2.綁定事件 注冊事件 // div.onclick // 3.添加事件處理程序 div.onclick = function() { console.log('我被選中了'); } </script> </body> </html>
常用的DOM事件
onclick事件---當(dāng)用戶點擊時執(zhí)行
onload事件---當(dāng)用戶進入時執(zhí)行
onunload事件---用用戶離開時執(zhí)行
onmouseover事件---當(dāng)用戶鼠標(biāo)指針移入時執(zhí)行
onmouseout事件---當(dāng)用戶鼠標(biāo)指針移出時執(zhí)行
onmousedown事件---當(dāng)用戶鼠標(biāo)摁下時執(zhí)行
onmouseup事件---當(dāng)用戶鼠標(biāo)松開時執(zhí)行
————————————————
版權(quán)聲明:本文為CSDN博主「那是我吶」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42402867/article/details/105567787
文章目錄
繼承性的描述:
繼承性是指被包在內(nèi)部的標(biāo)簽將擁有外部標(biāo)簽的樣式性,即子元素可以繼承父類的屬性。
例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ color: blue; } </style> </head> <body> <div>父元素 <div>子元素 <p>我依舊是子元素</p> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> p{ font-size: 32px; } </style> </head> <body> <p style="color: blue;">我這里體現(xiàn)了層疊性呀</p> </body> </html>
使用結(jié)論
由于內(nèi)容有限,但是結(jié)論是一定的,所以我直接給出結(jié)論:
若多個選擇器定義的樣式不沖突,則元素應(yīng)用所有選擇器定義的樣式。
若多個選擇器定義的樣式發(fā)生沖突(比如:同時定義了字體顏色屬性),則CSS按照選擇器的優(yōu)先級,讓元素應(yīng)用優(yōu)先級搞得選擇器樣式。
CSS定義的選擇器優(yōu)先級從高到低為:行內(nèi)樣式–>ID樣式–>類樣式–>標(biāo)記樣式。
如若想直接定義使用哪個樣式,不考慮優(yōu)先級的話,則使用!important,把這個加在樣式后面就行了。
優(yōu)先級
定義CSS樣式時,經(jīng)常出現(xiàn)兩個或更多規(guī)則應(yīng)用在同一個元素上,這時就會出現(xiàn)優(yōu)先級的問題。層疊性和選擇器的圈中有很大的關(guān)系。
優(yōu)先級的使用說明
權(quán)重分析:
內(nèi)聯(lián)樣式:如:style="",權(quán)重為1000。
ID選擇器,如:#content,權(quán)重為100。
類,偽類和屬性選擇器,如.content,權(quán)重為10。
標(biāo)簽選擇器和偽元素選擇器,如div p,權(quán)重為1。
繼承樣式,權(quán)重為0。
將基本選擇器的權(quán)重相加之和,就是權(quán)重大小,值越大,權(quán)重越高。
計算權(quán)重方法
數(shù)標(biāo)簽:先數(shù)權(quán)重最高的標(biāo)簽,然后數(shù)第二高權(quán)重的標(biāo)簽,以此類推,就會生成一個數(shù)組,里面包含四個數(shù)字。
比如(0,0,0,0)分別對應(yīng)(行內(nèi)式個數(shù),id選擇器個數(shù),類選擇器個數(shù),標(biāo)簽選擇器個數(shù))
然后兩個選擇器通過對別四個數(shù)字的大小,確定權(quán)重關(guān)系。
例:
#box ul li a.cur有1個id標(biāo)簽,1個類,3個標(biāo)簽,那么4個0就是(0,1,1,3)
.nav ul .active .cur有0個id,3個類,1個標(biāo)簽,那么4個0就是(0,0,3,1)
例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .p1{ color: blue; } #p1{ color: red; } </style> </head> <body> <p id="p1" class="p1">我們來試一下優(yōu)先級</p> </body> </html>
先推測一波,因為前面講到了ID選擇器的權(quán)重是大于類選擇器的,所以這里顏色應(yīng)該為red。
效果如下:
推測正確!優(yōu)先級GET!
今天講一下使用vant Swipe 輪播控件過程中遇到的問題
主要是使用swiper自定義的大小的時候,寬度適應(yīng)不同分辨率的移動設(shè)備
適應(yīng)寬度的同時還需控件的正常使用
先看一下需要實現(xiàn)的功能,
一個簡單的輪播圖,但是每個輪播的寬度需要低于100%,使第二個輪播的van-swipe-item可以展示到第一個位置一部分
這時我們再去vant的文檔查看一下控件
剛好有一個自定義控件大小的可以使用,完美解決了我們的問題
當(dāng)我們使用控件之后
<van-swipe :loop="false" @change="onChange" :width="350"> <van-swipe-item v-bind:id="item0"><div class="swipe0"> <div class="contion"> <p class="title">家中有事,申請請假一天</p> <p class="title1"><span class="rice"></span>部門經(jīng)理核審中</p> <p class="time">03.8 14.25</p> <p class="type">放假申請</p> </div> <img src="../../assets/images/index/xx/fangjia.png"> </div></van-swipe-item> <van-swipe-item ><div class="swipe1"></div></van-swipe-item> <van-swipe-item ><div class="swipe2"></div></van-swipe-item> <template #indicator> <div class="custom-indicator"> {{ current + 1 }}/3 </div> </template> </van-swipe>
發(fā)現(xiàn)功能可以使用,但是再 iPhone8/7 plus 以及iPhone5/se 等分辨率下出現(xiàn)了寬度固定而不適應(yīng)的情況,
簡單來說,我們把van-swipe-item寬度控制在了80% 第二個van-swipe-item自然可以展示出來一部分
但是當(dāng)滑到第二頁的時候 由于第一頁的寬度還是80% 所以就出現(xiàn)了這樣的情況,所以我打算采用
動態(tài)的改變 滑動到第幾頁的時候 把當(dāng)頁的寬度變?yōu)?0% 其他頁保持不變,
于是
<van-swipe :loop="false" @change="onChange" > <van-swipe-item v-bind:id="item0"><div class="swipe0"> <div class="contion"> <p class="title">家中有事,申請請假一天</p> <p class="title1"><span class="rice"></span>部門經(jīng)理核審中</p> <p class="time">03.8 14.25</p> <p class="type">放假申請</p> </div> <img src="../../assets/images/index/xx/fangjia.png"> </div></van-swipe-item> <van-swipe-item v-bind:id="item1"><div class="swipe1"></div></van-swipe-item> <van-swipe-item v-bind:id="item2"><div class="swipe2"></div></van-swipe-item> <template #indicator> <div class="custom-indicator"> {{ current + 1 }}/3 </div> </template> </van-swipe>
首先 我們?yōu)槊總€swipe-item添加id
data(){ return { android: true, ios: true, iphoneX: true, current: 0, item0:'item0', item1:'item1', item2:'item2', } }, mounted(){ }, methods: { onChange(index){ console.log('當(dāng)前 Swipe 索引:' + index); if(index==1){ var div =document.getElementById("item0").style.setProperty('width', '10rem', 'important'); var div1 =document.getElementById("item1").style.setProperty('width', '9.3333333rem', 'important'); var div2 =document.getElementById("item2").style.setProperty('width', '9.3333333rem', 'important'); } else if(index==2){ var div1 =document.getElementById("item1").style.setProperty('width', '10rem', 'important'); var div0 =document.getElementById("item0").style.setProperty('width', '10rem', 'important'); var div2 =document.getElementById("item2").style.setProperty('width', '9.3333333rem', 'important'); } else if(index==0){ var div =document.getElementById("item2"); var div0 =document.getElementById("item0").style.setProperty('width', '9.3333333rem', 'important'); var div1 =document.getElementById("item1").style.setProperty('width', '9.3333333rem', 'important'); } },
此外,監(jiān)聽滑動事件,根據(jù)滑動到第幾頁 更改當(dāng)前頁面的寬度,
這樣就解決了
蘭蘭設(shè)計:前端達(dá)人
藍(lán)藍(lán)設(shè)計的小編 http://www.teruid.com