display:none
完全消失
將會隱藏它以及全部的後代元素
佔據的空間消失,瀏覽器不會解析該元素
頁面產生迴流+重繪javascript
visibility:hidden
視覺消失能夠理解爲透明度爲0
佔據的空間仍存在,瀏覽器仍然會解析該元素
頁面產生重繪
visibility具備繼承性,父元素設置visibility:hidden,子元素也會繼承該屬性,當子元素從新設置visibility:visible,元素又會從新顯示,而display:none不會css
頁面的呈現流程html
some tips前端
迴流&重繪java
迴流:render tree中部分(所有)元素的規模尺寸佈局等改變而須要從新構建頁面。
重繪:render tree中一些元素須要更新屬性,但這些屬性隻影響元素的外觀、風格而不引發佈局的改變react
在解析樣式結構體的過程當中瀏覽器會去除不能識別的樣式
迴流必將引發重繪,重繪不必定引發迴流
參考文檔:關於呈現、迴流、重繪web
get:經過查詢字符串的方式來進行傳遞ajax
用於獲取少許信息(單次運輸量不大於64k),使用url傳遞參數->很不安全
post:經過表單的方式傳遞算法
用於修改服務器的資源,無信息量限制,採用請求體承載的方式,不易暴露
本質上同根同源
get&post 都是http協議中用於發送請求的方法,而http是基於tcp/ip的關於數據如何在萬維網通訊的協議
如何理解?
TCP->汽車 HTTP->交通規則 瀏覽器->運輸公司
get->將貨物放在車頂上(url) ,只產生一個數據包
post->將貨物放在車箱裏 , 產生header+body兩個數據包chrome
post產生兩個數據包,先發送header確認後再發送body,然而並非全部瀏覽器都在post中發兩次包,如firefox就只發一次
http:// www.baidu.com :8080 /dir/other.html 協議 主機名 端口 文件路徑 參數 文件片斷
transform
對元素進行移動、縮放、轉動、拉長或拉伸
方法:
translate():元素從當前位置移動根據給定的top left 座標移動
transform:tanslate(50px,30px)
rotate():元素順時針旋轉給定的角度,負值->逆時針旋轉
transform:rotata(20deg)
scale():根據給定的XY軸參數、元素的尺寸會增長或減小(拉伸、收縮)
transform:scale(1.2,0.8)
skew():翻轉
transform:skew(20deg, 20deg); //圍繞 X 軸把元素翻轉20度,圍繞 Y 軸翻轉20度
transition過渡
元素從一種樣式逐漸變爲另外一種樣式,屬於一種簡單的動畫屬性
四個屬性:
transition-property: 過渡屬性的樣式(默認值爲all)
transition-duration: 過渡持續時間(默認值爲0s)必須值
transiton-timing-function: 過渡函數(默認值爲ease函數)
transition-delay: 過渡延遲時間(默認值爲0s)
div{ width:100px; transition: width 1s; //時長爲一秒的寬度變化效果 } div:hover{ width:500px; }
參考:深刻理解trasition
參考:transition和transform
爲何用虛擬dom?
生成頁面時,瀏覽器從構建DOM樹開始從到到尾執行一遍流程。好比在一次操做時,須要更新10個DOM節點,理想狀態是一次性構建完DOM樹,再執行後續操做。可是瀏覽器並不會這麼作,收到第一個更新DOM請求後會立刻執行流程,所以須要執行10次。頻繁的操做會引發頁面卡頓。真實的DOM節點,哪怕最簡單的一個div也會包含不少屬性
虛擬DOM幹什麼?
如一次操做有10個更新DOM的動做,虛擬DOM不會馬上操做DOM,而是將10次更新的diff內容保存到一個本地的js對象中,最終將js對象一次行attach到DOM樹上,避免了大量的無謂計算量
虛擬的DOM的核心思想:對複雜的文檔DOM結構,提供一種方便的工具,進行最小化地DOM操做
三個狀態:裝配 更新 卸載
初始化渲染:
constructor()構造函數
componentWillMount組件將要加載(17版本棄用,在這裏請求異步數據,render可能不會渲染到,由於componentWillMount執行後,render立馬執行)
整個生命週期只調用一次(組件更新再也不調用)
render()渲染方法
componentDidMount 組件已經加載
整個生命週期只調用一次(組件更新再也不調用)
↑在這裏能夠異步請求數據,在這裏設置狀態會觸發從新渲染,可是不推薦使用setstate函數,會觸發額外一次渲染,且在瀏覽器刷新屏幕以前執行,會致使性能問題
更新:
共有五個環節(不一樣的狀況有不一樣的執行步驟)
1.componentWillReceiveProps(nextprops獲取更新狀態以及相應的組件狀態,組件將要接收參數
2.shouldComponentUpdate(nextprops,nextstate)根據下一個props和state決定組件是否應該更新
↑immutable data在此使用immutable是一旦建立,就不能再被更改的數據
3.componentWillUpdate()組件將要更新 作準備工做(定時、網絡請求等)
在這裏能夠更改state 可是不能使用setState函數 會引發函數調用componentshouldupdate從而進入死循環
4.render()渲染
getSnapshotBeforeUpdate(nextprops,nextstate)在更新前截圖//不會用
5.componentDidUpdate() 組件已經更新完畢
能夠在這裏獲取DOM
卸載
只有一個步驟,由於卸載後將失去控制能力
componentWillUnmount()組件將要卸載
在這裏清除一些不須要的監聽和計時器
三種模式下的執行步驟:
defaultProps()
設定默認props 在組件沒有被傳入時生效,避免報錯
propTypes 類型檢查
import PropTypes from 'prop-types'.//結合第三方prop-types庫 static propTypes = { title:PropTypes.string }
原型是JavaScript中繼承的基礎,JavaScript的繼承就是基於原型的繼承
什麼是原型?
咱們建立的每個函數都有一個prototype屬性,這個屬性是一個指針,指向一個對象,這個對象能夠包含由特定類型的全部實例共享的屬性和方法。而prototype就是經過調用構造函數建立的對象實例的原型對象
原型所指的就是一個對象,實例繼承對象的屬性。在原型上定義的屬性,經過繼承,實例也擁有了這個屬性
實例經過_proto_這個屬性直接訪問到原型
function Person(){ Person.prototype.type = 'object named Person'; person = new Person(); person._proto_ === Person.prototype;//二者等價 }
構造函數->prototype->訪問原型
原型->constructor->訪問構造函數
使用原型的好處:
可讓對象的實例共享它所包含的屬性和方法,沒必要在構造函數中添加定義對象信息,而是能夠將這些信息添加到原型中(若是使用構造函數就要讓每一個方法都在實例中建立一遍)
constructor是原型的一個屬性,Constructor是真正的構造函數
什麼是原型鏈?
_proto_是實例指向原型對象的一個指針,是任何對象都有的屬性,js萬物皆對象,因此就造成了一條由_proto_連起來的鏈條,遞歸訪問到頭,終值爲null
在讀取一個實例的屬性時,若是該屬性在當前實例沒有找到,那麼就會循着_proto_指定的原型繼續向上找,若是還找不到,則尋找原型的原型,若是一直沒有找到,則直到搜索到null爲止
原型繼承
Son.prototype = new Father();//Son繼承了Father,經過原型,造成鏈條
變量提高
ES6以前沒有塊級做用域,只有全局做用域和局部做用域,變量提高就是將變量聲明提高到它所在做用域的最開始的部分
函數提高
建立函數有兩種形式:函數聲明和函數字面量,只有函數聲明有變量提高
console.log(a) // f a() { console.log(a) } console.log(b) //undefined,不存在函數提高 function a() { console.log(a) } var b = function(){ console.log(b) }
函數提高與變量提高的優先級
函數提高要比變量提高的優先級要高一些,且不會被變量聲明覆蓋,可是會被變量賦值以後覆蓋。
console.log(a); // f a() {console.log(10)} console.log(a()); // undefined var a = 3; function a() { console.log(10) //10 } console.log(a) //3 a = 6; console.log(a()); //a is not a function;
正常的執行順序
var a = funtion () { console.log(10) } var a; console.log(a); // f a() {console.log(10)} console.log(a()); // undefined a = 3; console.log(a) //3 a = 6; console.log(a()); //a() is not a function;
//f2() jQuery.subscribe("done", f2); //f1() function f1(){ setTimeout(function () { // f1的任務代碼 jQuery.publish("done"); }, 1000); } //f2執行完畢後能夠取消訂閱 jQuery.unsubscribe("done", f2);
該方法優於事件監聽,能夠經過查看消息中心瞭解如今有多少信號、訂閱者,從而監控程序的執行狀態
參考文檔
優勢:容易理解和部署
缺點:不利於代碼閱讀、維護,各個部分耦合性很高,流程混亂,且每一個任務只能指定一個回調函數
什麼是跨域:
瀏覽器不能執行其餘網站的腳本,由瀏覽器的同源策略形成,是瀏覽器對JavaScript施加的安全限制
判讀是同域:
相同域名,端口相同,協議相同
Jsonp:
Json with Padding,爲了解決跨域請求資源而產生的解決方案,是一種依靠開發人員創造出的一種非官方跨域數據交互協議。
Jsonp的產生:
ajax直接請求普通文件存在跨域無權限訪問的問題,而web頁面調用js時不受跨域影響,凡是帶有src屬性標籤的都擁有跨域能力->在遠程服務器上把數據裝進js格式的文件裏,能夠實現跨域訪問
JSON的純字符數據格式能夠簡潔的描述複雜的程序,JSON還被原生js支持
因此,web客戶端調用跨域服務器生成的js文件(JSON),便得到了本身想要的數據
Jsonp原理
利用script標籤沒有跨域限制的「漏洞」達到和第三方通信的目的
首先在客戶端註冊一個回調函數,而後把回調函數的名字傳給服務器,這時服務器生成json數據,以JavaScript的方式生成function,將jasonp以入參的方式放到function裏,生成JavaScript文檔,返回給客戶端,瀏覽器解析這個script,執行JavaScript文檔,此時數據做爲參數傳入了客戶端以前定義的回調函數裏。
jsonp是請求以後後臺包裝好一段json,而且把數據放在一個callback函數,返回一個js文件,動態引入這個文件,下載完成js以後,會去調用這個callback,經過這樣訪問數據
json 是一種數據格式,jsonp 是一種數據調用的方式,帶callback的json就是jsonp
跨域的幾種方法
把可以接受多個參數的函數變換成接受一個單一參數的函數,而且返回接受餘下參數並且返回結果的函數技術
柯里化是指這樣一個函數(假設叫作createCurry),他接收函數A做爲參數,運行後可以返回一個新的函數。而且這個新的函數可以處理函數A的剩餘參數。
函數柯里化(function currying)又稱部分求值。一個currying的函數首先會接受一些參數,接受了這些參數後,該函數並不會當即求值,而是繼續返回另一個函數,剛纔傳入的參數在函數造成的閉包裏被保存起來。待到函數真正須要求值的時候,以前傳入的參數都會被一次性用於求值。
Q:函數通過createCurry轉化爲一個柯里化函數,最後執行的結果,不是正好至關於執行函數自身嗎?柯里化是否是把簡單的問題複雜化了?
好處:
1.參數複用
2.提早返回
3.延時執行
對模塊化的理解
功能封裝,針對Javascript代碼,隔離、組織複製的javascript代碼,將它封裝成一個個具備特定功能的的模塊。
模塊能夠經過傳遞參數的不一樣修改這個功能的的相關配置,每一個模塊都是一個單獨的做用域,根據須要調用。
模塊化就是爲了減小系統耦合度,提升內聚性,減小資源循環依賴,加強系統框架設計。
CommonJs
它的終極目標是提供一個相似Python,Ruby和Java標準庫。這樣的話,開發者可使用CommonJS API編寫應用程序,而後這些應用能夠運行在不一樣的JavaScript解釋器和不一樣的主機環境中。
CommonJs的特色:
AMD規範和commonJS規範
1.相同點:都是爲了模塊化。
2.不一樣點:AMD規範則是非同步加載模塊,容許指定回調函數。CommonJS規範加載模塊是同步的,也就是說,只有加載完成,才能執行後面的操做。
參考文檔
利用jQuery實現圖片懶加載的原理。它的基本思想是:在輸出HTML的時候,不要直接輸出<img src="xxx",而是輸出以下的img標籤:
<img src="/static/loading.gif" data-src="http://真正的圖片地址/xxx.jpg">
監聽scroll事件,調用目標元素(綠色方塊)的getBoundingClientRect()方法,獲得它對應於視口左上角的座標,再判斷是否在視口以內。這種方法的缺點是,因爲scroll事件密集發生,計算量很大,容易形成性能問題。
使用IntersectionObserve(callback,option) api監聽圖片素到視口的距離判斷是否加載圖片,實現懶加載
callback通常會觸發兩次。一次是目標元素剛剛進入視口(開始可見),另外一次是徹底離開視口(開始不可見)。
參考
有些事件(resize Mousemove scroll)幾乎是不間斷觸發的,若是存在複雜的函數方法,很是影響性能,因此須要函數節流
函數節流的基本思想是設置一個定時器,在指定時間間隔內運行代碼時清除上一次的定時器,並設置另外一個定時器,直到函數請求中止並超過期間間隔纔會執行。
一個函數執行一次後,只有大於設定的執行週期後纔會執行第二次
函數的節流和函數的去抖都是經過減小實際邏輯處理過程的執行來提升事件處理函數運行性能的手段,並無實質上減小事件的觸發次數。
節流和防抖的區別
函數節流是指必定時間內js方法只跑一次。
好比人的眨眼睛,就是必定時間內眨一次。這是函數節流最形象的解釋。
函數防抖是指頻繁觸發的狀況下,只有足夠的空閒時間,才執行代碼一次。
好比生活中的坐公交,就是必定時間內,若是有人陸續刷卡上車,司機就不會開車。只有別人沒刷卡了,司機纔開車。
代碼實現
節流
聲明一個變量爲標誌位,當這個變量爲true的時候,表明如今的滾動處理事件是空閒的,可使用。直接return並將變量設爲false這樣,其餘請求執行滾動事件的方法,就被擋回去了。而後用settimeout規定時間間隔,再執行定時函數內的代碼,執行完畢將變量從新設爲true
防抖
也須要一個settimeout輔助,延遲執行須要跑的代碼
若是方法屢次觸發,則把上次記錄的延遲執行代碼用clearTimeout清掉,從新開始。
若是計時完畢,沒有方法進來訪問觸發,則執行代碼。
函數防抖的實現重點,就是巧用setTimeout作緩存池,並且能夠輕易地清除待執行的代碼。clearTimeout(timer)
參考
只要父組件的render了,那麼默認狀況下就會觸發子組件的render過程,子組件的render過程又會觸發它的子組件的render過程,一直到React元素(即jsx中的<div>這樣的元素)。當render過程到了葉子節點,即React元素的時候,diff過程便開始了,這時候diff算法會決定是否切實更新DOM元素。
React不能檢測到你是否給子組件傳了屬性,因此它必須進行這個重渲染過程(術語叫作reconciliation)
連接描述
let、const、var的區別
var:能夠跨塊級做用域訪問,不能跨函數做用域訪問
let:只能在塊級做用域訪問,不能跨函數使用
const:定義常量,必須初始化且不能修改,只能在塊級做用域內使用
關於變量提高:var不論聲明在何處都會莫默認提高到函數/全局最頂部,可是let和const不會進行變量提高
function sleep(ms){ return new Promise((resolve)=>setTimeout(resolve,ms)); } async function test(){ var temple=await sleep(1000); console.log(1111) return temple } test(); //延遲1000ms輸出了1111
promise由於沒有代碼塊,因此不能在一個返回的箭頭函數中設置斷點。若是你在一個 .then 代碼塊中使用調試器的步進(step-over)功能,調試器並不會進入後續的 .then 代碼塊,由於調試器只能跟蹤同步代碼的每一步。
使用 async/await,你就沒必要再使用箭頭函數。你能夠對 await 語句執行步進操做
傳統算法就是對每一個節點一一對比,循環遍歷全部的子節點,而後判斷子節點的更新狀態,分別爲remove、add、change。若是before的子節點仍有子節點依舊順次執行。
主要思想是給予容器控制內部元素高度和寬度的能力
主軸main axis 縱軸 cross axis
1點:
display: flex; justify-content: center; align-items:center;
2點:豎列布局且在主軸方向採用justify-content的兩端對齊佈局,這樣兩個圓點會在左邊呈現,而後採用align-items讓其居中
display: flex; flex-direction: column;//垂直顯示 justify-content: space-between; align-items:center;
3點:用到align-self屬性讓第二個和第三個圓點有本身的屬性設置,分別在縱軸方向上居中和低端對齊
.item:nth-child(2){ align-self:center; } .item:nth-child(3){ align-self:flex-end; }
五點佈局
思路:先豎着放兩行圓點,每行圓點裏橫着放兩個圓點,因此最外層父元素設置align,裏面的父元素設置justify-content造成4點
讓圓點(即子元素)在橫軸上居中在豎軸上居中,分別用justify-content和align-items造成1點
display: flex; flex-wrap:wrap;//必要時拆行顯示 align-content:space-between;//各行在彈性盒容器中平均分佈 .column{ flex-basis:100%; display:flex; justify-content: space-between; }
6點:
跟四點的同樣,先豎放三行在每行橫放兩個圓點
一個網頁可能有許多的小圖標,訪問時會發送不少次的請求,形成資源浪費、訪問速度變慢。可使用一張圖片來代替小圖標,按必定的距離排開
前提條件
須要一個寬和高設置好的容器
須要設置background-position的值(默認爲(0,0),也就是圖片的左上角),即移動圖片到本身想要的圖標位置。
用css Gaga 自動生成雪碧圖
css代碼爲:background-position:-xpx -ypx;
1.XSS攻擊:
跨站腳本攻擊指的是惡意攻擊者往Web頁面裏插入惡意html代碼,當用戶瀏覽該頁之時,嵌入的惡意html代碼會被執行,對受害用戶可能採起Cookie資料竊取、會話劫持、釣魚欺騙等各類攻擊。
預防方法:
2.CSRF跨站點僞造請求
攻擊者經過各類方法僞造一個請求,模仿用戶提交表單的行爲,從而達到修改用戶的數據,或者執行特定任務的目的。
解決方法:
3.Http Heads攻擊
HTTP協議在Response header和content之間,有一個空行,即兩組CRLF(0x0D 0A)字符。這個空行標誌着headers的結束和content的開始。「聰明」的攻擊者能夠利用這一點。只要攻擊者有辦法將任意字符「注入」到headers中,這種攻擊就能夠發生。
解決辦法:
服務器通常會限制request headers的大小。例如Apache server默認限制request header爲8K。若是超過8K,Aapche Server將會返回400 Bad Request響應。
對於大多數狀況,8K是足夠大的。假設應用程序把用戶輸入的某內容保存在cookie中,就有可能超過8K.攻擊者把超過8k的header連接發給受害者,就會被服務器拒絕訪問.解決辦法就是檢查cookie的大小,限制新cookie的總大寫,減小因header過大而產生的拒絕訪問攻擊
參考
閉包
垂直居中實現
redux原理