原文首發於個人博客,歡迎關注~css
我已經入職字節跳動實習啦~~,有對前端感興趣的同窗能夠隨時找我內推喲,郵箱:html
職位描述前端
職位要求:vue
即將面試今日頭條的前端實習,這次必定要作好充足準備,特打算花個幾天的時間對前端來一個系統性的梳理(前端太龐大,其實也只能包含一小部分哈哈)。雖然檢查了不少遍,可能仍有錯誤,若是發現,請指正,謝謝!git
本文參考了不少資料,特別須要感謝的有:es6
參考:github.com/lukehoban/e…github
Promise 與回調函數同樣用來管理 JS 中的異步編程,它的提出解決了層層回調函數嵌套形成的回調地獄。new Promise的時候,會把傳遞的函數當即執行。Promise函數天生有兩個參數,resolve(當異步操做執行成功,執行resolve方法),rejected(當異步操做失敗,執行reject方法) 。面試
經過使用 Promise 的 .then()
方法,能夠註冊回調函數,並在 Promise resolved 以後被調用,then
能夠返回一個新的 Promise,Promise 將會 resolve 爲 then
註冊的函數中的返回值,這樣實現了鏈式的回調函數註冊。Promise 有三種可能狀態,pending、fulfilled(成功)、rejected(失敗)。一個 Promise 一旦 resolve 或者 reject 狀態就再也不改變。能夠用 .catch()
獲取 reject 的 Promise 的緣由,也能夠用 .then()
第二個參數獲取。另外還有 Promise.all
、Promise.race
等等。ajax
相關代碼以下(來源:github.com/Molunerfinn… ):正則表達式
// 實現 Promise.race,resolve 或 reject 第一個便可
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (const item of promises) {
Promise.resolve(item).then(res => {
resolve(res)
}, err => {
reject(err)
})
}
})
}
// 實現Promise.all
Promise.all = function (promises) {
const length = promises.length
let count = 0
const result = new Array(length) // 暫存結果
return new Promise((resolve, reject) => {
for (const item in promises) {
Promise.resolve(promises[item]).then(res => {
count++
// Promise.all 輸出結果順序是按傳入的promise的順序來的
result[item] = res
if (count === length) { // 所有完成再 resolve
return resolve(result)
}
}, err => {
reject(err) // 一旦有 reject,就 reject
})
}
})
}
複製代碼
相應的,還有 async
、await
。
異步編程四種方法:
function print(a = 'test') {
console.log(a)
}
print() // test
print('Hello') // Hello
複製代碼
另外還有:
模板字符串(能夠嵌套)
解構賦值(數組、對象)
展開語法 ...
,接收剩餘參數、將數組轉換爲逗號分隔的變量
塊級做用域 let
、const
,無變量提高,不容許重複聲明
迭代器和 for
... of
生成器
function* d() { // Generator 函數。它不一樣於普通函數,是能夠暫停執行的,因此函數名以前要加星號,以示區別。
for (let i = 0; i < 3; i++) {
yield i * i
}
}
for (let i of d()) { // 調用 Generator 函數,會返回一個內部指針(即迭代器/遍歷器 ),即執行它不會返回結果,返回的是指針對象
console.log(i) // 0, 1, 4
}
console.log(d().next()) // {value: 0, done: false},調用指針對象的 next 方法,會移動內部指針;next 方法的做用是分階段執行 Generator 函數
複製代碼
模塊,import
、export
模塊加載器
Map + Set + WeakMap(只接受對象鍵名,且是弱引用) + WeakSet
箭頭函數,箭頭函數沒有 arguments
實參集合,取而代之用 ...
運算符
全部 var
聲明都會被提高到做用域的最頂上
同一個變量聲明只進行一次
console.log(foo) // undefined,剛剛聲明完成可是並未賦值
var foo = 3
console.log(foo) // 3,完成賦值
var foo = 5
console.log(foo) // 5,再次賦值
複製代碼
函數聲明的優先級優於變量聲明,且函數聲明會連帶定義一塊兒被提高
console.log(foo) // 輸出 `foo() {}`
function foo() {}
foo = 5
複製代碼
注意只有 var
才能提高,不帶 var
的全局變量仍是按照順序聲明
console.log(foo) // Uncaught ReferenceError: foo is not defined
foo = 3
foo = 5
複製代碼
在 ES5 中,js 只有兩種形式的做用域:全局做用域和函數做用域。
先來看看 var
:
(function() {
var a = b = 5;
})();
var c = 55
console.log(window.c) // 55,var 做用域存在於所定義的函數,不然(沒有外圍函數)就屬於 window(瀏覽器)/global(Node.js)
console.log(b); // 5,b 沒有關鍵字 var,是全局變量
console.log(window.b); // 5,全局變量也屬於 window 對象
console.log(a); // undefined,離開了 a 的做用域
複製代碼
在 ES6 中,新增長的 let/const
讓 塊級做用域(block scope) 成爲現實,在js中常見到的 if{}
、for{}
、while{}
、try{}
、catch{}
、switch case{}
甚至直接單純的 {}
這種帶花括號的都是塊級做用域,var obj = {}
中對象的大括號不是塊級做用域。塊級做用域中的同一變量不能被重複聲明(塊級下 let
不能重複定義,嚴格模式下 function 也不能重複聲明)。
this
指向this
的指向和 var
很相似,this
老是指向調用這個函數的對象,根據 this
所在的函數主要分爲兩種狀況:
若是此函數是一個對象 obj
的成員,咱們稱之爲方法(method),this
指向方法所屬對象 obj
。
const video = {
title: 'a',
play() {
console.log(this)
}
}
video.play() // Object {title: "a", play: function play()}
video.stop = function() {
console.log(this)
}
video.stop() // Object {title: "a", play: function play()}
複製代碼
若是此函數是一個普通函數,即不是某個對象的一部分,this
指向 window(瀏覽器)/global(Node.js),若是是嚴格模式則是 undefined
。
function playVideo() {
console.log(this)
}
playVideo() // Window
複製代碼
構造函數同 1 相似,this
指向新建立的對象。
function Video(title) {
this.title = title
console.log(this)
}
const v = new Video('b') // Video {title: "b"}
複製代碼
回調函數,this
指向 window(瀏覽器)/global(Node.js)。
function Video(title) {
this.title = title
console.log(this)
const arr = [1, 2, 3]
arr.forEach(function(ele) {
console.log(this) // 三次打印 Window,要使 `this` 指向新建的 Video,有兩種方法:
// 1. forEach 在 callback 參數以後能夠添加 `thisArg` 參數
// 2. 使用 ES6 中新增的箭頭函數
})
}
const v = new Video('b')
複製代碼
箭頭函數,this
指向外層函數的 this
,而且不能用 call
進行指定。
const obj = {
a: () => {
console.log(this)
}
}
obj.a() // Window
obj.a.call('123') // Window
複製代碼
元素監聽函數,指向元素自己。
let button = document.getElementById('button')
button.addEventListener('click', function(e) {
console.log(this) // <button id="button">測試 this</button>
})
複製代碼
簡單來講閉包就是在函數裏面聲明函數並返回,當一個函數可以訪問和操做另外一個函數做用域中的變量時,就構成了一個閉包(Closure)。咱們要記住函數在執行時使用的是聲明時所處的做用域鏈,而不是調用時的做用域鏈。
function addTo(base) {
let sum = base
return function(b) {
sum += b
return sum
}
}
let add = addTo(2)
console.log(add(4)) // 6
console.log(add(5)) // 11
複製代碼
同源策略指的是協議、域名、端口相同,一段腳本只能讀取來自同源的信息。注意子域名也不一樣源。
同源策略限制是有道理的,假設沒有同源策略,黑客能夠利用 IFrame 把真正的銀行登錄界面嵌入到他的頁面上,當你使用真實用戶名、密碼登陸時,他的頁面就能夠經過 JS 讀取到 Iframe 中 input 中的內容、你使用的 Cookie 等,可以輕鬆盜取用戶信息。
跨域主要有如下幾種方法:
<script>
的 src
屬性(相似的還有 href
屬性)不受同源策略限制,咱們在 js 中定義回調函數 callback(data)
接收服務器傳來的 data
,請求時必須指定回調函數名稱,服務器動態生成 js 腳本對本地的 js callback
進行調用並傳入服務端查詢獲得的 data
數據。注意 jsonp 只能解決 GET 請求。document.domain = ...
。腳本能夠將 document.domain 的值設置爲其當前域或其當前域的父域。注意,company.com 不能設置 document.domain 爲 othercompany.com,由於它不是 company.com 的父域。Access-Control-Allow-Origin: *
便可像普通 ajax 同樣訪問跨域資源。注意如請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json,稱爲非簡單請求,在正式通訊以前,還須要增長一次預檢請求(preflight)。用到的頭部有 Access-Control-Request-Method
、Access-Control-Request-Headers
、Access-Control-Allow-Methods
、Access-Control-Allow-Headers
、Access-Control-Allow-Credentials
(發送Cookie和HTTP認證信息)。window.postMessage()
。現代瀏覽器中多窗口通訊使用 HTML5 規範的 targetWindow.postMessage(data, origin);其中 data 是須要發送的對象,origin 是目標窗口的 origin。window.addEventListener('message', handler, false);handler 的 event.data 是 postMessage 發送來的數據,event.origin 是發送窗口的 origin,event.source 是發送消息的窗口引用。相同點:保存在瀏覽器,同源。
不一樣點
window.sessionStorage
和 window.localStorage
不會自動把數據發給服務器,僅在本地保存;call
vs apply
vs bind
call
和 apply
都是用來改變函數執行的時候的 this
和參數。惟一不一樣的是 call
傳入逗號(comma)分隔的參數,apply
傳入數組(array)做爲參數。
bind
返回一個新的函數,傳入一個 this
參數和逗號分隔的參數,新返回的函數執行時使用給定的 this
和參數。
若是要本身實現這三個函數的話,核心的思路就是:
Function.prototype.newCall = function (context, ...args){
//...
context.fn = this // 當前調用 newCall 的函數
const
result = context.fn(...args) // 此處調用時改變了this指向,fn的this指向context
// ...
}
複製代碼
參考:segmentfault.com/a/119000000…
事件流描述的是從頁面中接收事件的順序,也可理解爲事件在頁面中傳播的順序。
事件冒泡和事件捕獲分別由微軟和網景公司提出,在事件捕獲的概念下在p元素上發生click事件的順序應該是document -> html -> body -> div -> p,在事件冒泡的概念下在p元素上發生click事件的順序應該是p -> div -> body -> html -> document。
addEventListener有三個參數:
element.addEventListener(event, function, useCapture) 複製代碼
第三個參數默認值是false,表示在事件冒泡階段調用事件處理函數;若是參數爲true,則表示在事件捕獲階段調用處理函數。點擊下面的 s2 按鈕查看效果。
See the Pen event capture and bubbling by Li Yiming (@upupming) on CodePen.
注意:對於target節點上(這裏的 s2),是先捕獲仍是先冒泡則捕獲事件和冒泡事件的註冊順序,先註冊先執行)。
阻止冒泡:
function stopBubble(e) {
if (e && e.stopPropagation) { // 若是提供了事件對象event 這說明不是IE瀏覽器
e.stopPropagation()
} else {
window.event.cancelBubble = true //IE方式阻止冒泡
}
複製代碼
See the Pen 事件代理 by Li Yiming (@upupming) on CodePen.
IE瀏覽器對addEventListener兼容性並不算太好,只有IE9以上可使用。
要兼容舊版本的IE瀏覽器,可使用IE的attachEvent函數
object.attachEvent(event, function) 複製代碼
兩個參數與addEventListener類似,分別是事件和處理函數,默認是事件冒泡階段調用處理函數,要注意的是,寫事件名時候要加上"on"前綴("onload"、"onclick"等)。
typeof
vs. instanceof
參考:stackoverflow.com/questions/8…
typeof
用來判斷簡單原始類型(primitive types),instanceof
用來判斷複雜原始類型、Object、自定義數據類型。
/** 簡單原始類型 */
'example string' instanceof String; // false
typeof 'example string' == 'string'; // true,string 類型用 typeof
'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false
true instanceof Boolean; // false
typeof true == 'boolean'; // true,boolean 類型用 typeof
99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true,number 類型用 typeof
function() {} instanceof Function; // true
typeof function() {} == 'function'; // true,function 類型用 typeof、instanceof 都可
/** 複雜原始類型 */
/regularexpression/ instanceof RegExp; // true,正則表達式用 instanceof
typeof /regularexpression/; // object
[] instanceof Array; // true,array 用 instanceof
typeof []; //object
{} instanceof Object; // true,object 用 instanceof
typeof {}; // object
/** 自定義類型 */
var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false
複製代碼
除了上面的 instanceof
外還有以下方法:
// Array API
Array.isArray(arr)
// Object類型的toString會返回[object type],其中type是類型
// 可是有的對象的toString方法會被改寫
// 因此須要借用一下Object原始的toString
return Object.prototype.toString.call(arr) === '[object Array]'
// 利用自定義對象的 constructor
arr.constructor.name === 'Array'
複製代碼
instanceof
循環使用 Object.getPrototypeOf()
便可:
// getPrototypeOf 可同時用於對象和原型,不能直接用於類型(直接返回 Function.prototype)
Object.getPrototypeOf([]) === Array.prototype // true
Object.getPrototypeOf(Array.prototype) === Object.prototype // true
Object.getPrototypeOf(Array) == Function.prototype // true
let newInstanceOf = function (left, right) {
// 檢查必須是複雜數據類型
if (typeof left !== 'object' && typeof left !== 'function') {
return false
}
right = right.prototype
do {
left = Object.getPrototypeOf(left)
if (left === right) return true
} while (left !== null)
return false
}
複製代碼
也可使用 isPrototypeOf
直接檢查對象是否在另外一對象的其原型鏈上:
Object.prototype.isPrototypeOf([]) // true
Array.prototype.isPrototypeOf([]) // true
複製代碼
另外注意 hasOwnProperty
在執行對象查找時,始終不會查找原型。
==
vs ===
==
:容許不一樣數據類型之間的比較,若是是不一樣類型的數據進行比較,會默認進行數據類型之間的轉換,若是是對象數據類型的比較,比較的是空間地址;
a = [1, 2]
b = [1, 2]
// 比較地址空間
a == b // false
_.isEqual(array1, array2) // true,使用 Lodash 庫進行比較,或者本身一個一個元素進行比較
false
複製代碼
===
:只要數據類型不同,就返回false。
防抖是說連續兩次的調用必須間隔指定的時間,節流是說當調用一次以後,必須在指定時間以後的調用纔會有效。
具體使用場景:
resize
調整窗口大小,由於一次窗口調整中間會出發出至關多的時間間隔很短的 resize
事件,那麼防抖主要是看用戶進行調整的總次數,而節流看的是每一次調整時,用戶的 resize
的手速有多快。front end
,當你輸入前面的 f
或者 front
時就會出現候選結果。可是由於 API 調用消耗很大,因此會使用防抖來較少調用次數,這符合用戶停頓時就是想看到搜索結果的現實邏輯。實現以下:
function debounce(func, limit) {
let timer
return function (...args) {
// 前一次還沒來得及執行的話,取消掉前一次的
clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, limit)
}
}
function throttle(func, limit) {
let flag = true
return function(...args) {
if (flag) {
func.apply(this, args)
flag = false
// 只有通過指定時間後,才能夠執行新的
setTimeout(() => {
flag = true
}, limit)
}
}
}
複製代碼
在非IE瀏覽器(如Firefox)下,當容器的高度爲auto,且容器的內容中有浮動(float爲left或right)的元素,在這種狀況下,容器的高度不能自動伸長以適應內容的高度,使得內容溢出到容器外面而影響(甚至破壞)佈局的現象。這個現象叫浮動溢出,爲了防止這個現象的出現而進行的CSS處理,就叫CSS清除浮動。
inline-block
,其 margin: 0 auto
居中方式失效overflow:hidden
See the Pen 聖盃佈局 by Li Yiming (@upupming) on CodePen.
See the Pen 雙飛翼佈局 by Li Yiming (@upupming) on CodePen.
ajax的原理:至關於在用戶和服務器之間加一箇中間層(ajax引擎),使用戶操做與服務器響應異步化。
怎麼解決呢?經過location.hash
值來解決Ajax過程當中致使的瀏覽器前進後退按鍵失效, 解決之前被人常遇到的重複加載的問題。主要比較先後的hash值,看其是否相等,在判斷是否觸發ajax。
function getData(url) {
var xhr = new XMLHttpRequest(); // 建立一個對象,建立一個異步調用的對象
xhr.open('get', url, true) // 設置一個http請求,設置請求的方式,url以及驗證身份
xhr.send() //發送一個http請求
xhr.onreadystatechange = function () { //設置一個http請求狀態的函數
if (xhr.readyState == 4 && xhr.status ==200) {
console.log(xhr.responseText) // 獲取異步調用返回的數據
}
}
}
複製代碼
AJAX狀態碼:
setTimeout
實現 setInterval
基本思想:
function mySetInterval(handler, timeout, ...arguments) {
const fn = () => { // 關鍵在於構造 fn 反覆調用 handler
handler()
setTimeout(fn, timeout)
}
setTimeout(fn, timeout)
}
mySetInterval(() => {
console.log(`bla bla...`)
}, 1000)
複製代碼
另外,還能夠實現 clearTimeInterval
(利用全局 obj
存儲自增的 id
到 timeId
的映射) 和 arguments
自定義參數。
JavaScript 的併發模型基於「事件循環」。這個模型與像 C 或者 Java 這種其它語言中的模型大相徑庭。
一個 JavaScript 運行時包含了一個待處理的消息隊列。每個消息都關聯着一個用以處理這個消息的函數。
在事件循環期間的某個時刻,運行時從最早進入隊列的消息開始處理隊列中的消息。爲此,這個消息會被移出隊列,並做爲輸入參數調用與之關聯的函數。調用一個函數老是會爲其創造一個新的棧幀。函數的處理會一直進行到執行棧再次爲空爲止;而後事件循環將會處理隊列中的下一個消息(若是還有的話)。
Event Loop是一個程序結構,用於等待和發送消息和事件。常見形式:
while (queue.waitForMessage()) {
queue.processNextMessage();
}
複製代碼
const s = new Date().getSeconds();
setTimeout(function() {
// 輸出 "2",表示回調函數並無在 500 毫秒以後當即執行
// 而是等待下面的 while 執行完以後纔開始執行
// 在瀏覽器裏,當一個事件發生且有一個事件監聽器綁定在該事件上時,消息會被隨時添加進隊列。
// 500ms事後,WebAPIs把此函數放入任務隊列,此時while循環還在棧中,此函數須要等待;
console.log("Ran after " + (new Date().getSeconds() - s) + " seconds");
}, 500);
while(true) {
// while循環執行完畢從棧中彈出,main()彈出,此時棧爲空,Event Loop,setTimeout中的回調函數進入棧
if(new Date().getSeconds() - s >= 2) {
console.log("Good, looped for 2 seconds");
break;
}
}
複製代碼
class
& interface
在es6中,咱們有一種新的關鍵字class
來定義一個類;咱們能夠繼承方法和屬性,使用extends
關鍵字繼承;其實本質上,仍是使用原型鏈的方式繼承,只是給了更好理解的語法糖;Typescript在 class
的基礎上添加了訪問修飾符和接口 interface
。
property:屬性,attribute:特性
attribute 是 DOM 元素在文檔中做爲 HTML 標籤擁有的屬性;property 是 DOM 元素在 JavaScript 中做爲對象擁有的屬性。
input.value
、input.id
、input.disabled
、a1.href
等等attributes
屬性中,經常使用方法:getAttribute
、setAttribute
、removeAttribute
;value
,class
這樣的屬性/特性,數據綁定的方向是單向的,attribute->property;id
而言,數據綁定是雙向的,attribute<=>property;disabled
而言,property上的disabled設置爲false時,會移除attribute上的 disabled
,反之亦然,此時數據綁定能夠認爲是雙向的;置換元素(replaced element)主要是指 img, input, textarea, select, object 等這類默認就有 CSS 格式化外表範圍的元素。進而可知,非置換元素(non-replaced element)就是除了 img, input, textarea, select, object 等置換元素之外的元素。
在 CSS 中,可替換元素(replaced element)的展示效果不是由 CSS 來控制的。這些元素是一種外部對象,它們外觀的渲染,是獨立於 CSS 的。
background-color 規定要使用的背景顏色。
background-position 規定背景圖像的位置。
background-size 規定背景圖片的尺寸。
background-repeat 規定如何重複背景圖像。
background-origin 規定背景圖片的定位區域。
background-clip 規定背景的繪製區域。
background-attachment 規定背景圖像是否固定或者隨着頁面的其他部分滾動。
background-image 規定要使用的背景圖像。
inherit 規定應該從父元素繼承 background 屬性的設置。
box-sizing: content-box
(默認)
總寬度 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
若是你設置一個元素的寬爲 100px,那麼這個元素的內容區會有 100px 寬,而且任何邊框和內邊距的寬度都會被增長到最後繪製出來的元素寬度中。
box-sizing: border-box
總寬度 = margin-left + width + margin-right
你想要設置的邊框和內邊距的值是包含在width內的。也就是說,若是你將一個元素的width設爲100px,那麼這100px會包含它的border和padding,內容區的實際寬度是width減去(border + padding)的值。大多數狀況下,這使得咱們更容易地設定一個元素的寬高。
在ie8+瀏覽器中使用哪一個盒模型能夠由box-sizing(CSS新增的屬性)控制,默認值爲content-box,即標準盒模型;若是將box-sizing設爲border-box則用的是IE盒模型。若是在ie6,7,8中DOCTYPE缺失會觸發IE模式。在當前W3C標準中盒模型是能夠經過box-sizing自由的進行切換的。
利用標準盒模型便可:
See the Pen VwwdxXr by Li Yiming (@upupming) on CodePen.
參考:www.w3schools.com/cssref/trys…
static
、relative
、absolute
、fixed
參考:www.cnblogs.com/theWayToAce…
static
(靜態定位):默認值。沒有定位,元素出如今正常的流中(忽略 top, bottom, left, right 或者 z-index 聲明)。
relative
(相對定位):生成相對定位的元素,經過top,bottom,left,right的設置相對於其正常(原先自己)位置進行定位。可經過z-index進行層次分級。
absolute
(絕對定位):生成絕對定位的元素,相對於 static 定位之外的第一個父元素進行定位。元素的位置經過 "left", "top", "right" 以及 "bottom" 屬性進行規定。可經過z-index進行層次分級。
fixed
(固定定位):生成絕對定位的元素,相對於瀏覽器窗口進行定位。元素的位置經過 "left", "top", "right" 以及 "bottom" 屬性進行規定。可經過z-index進行層次分級。
定位於父級內部某個位置的元素,最好用 absolute,由於它不受父級元素的padding的屬性影響,固然你也能夠用relative,不過到時候計算的時候不要忘記padding的值。
inline
vs. inline-block
vs. block
block和inline這兩個概念是簡略的說法,完整確切的說應該是 block-level elements (塊級元素) 和 inline elements (內聯元素)。
block元素一般被現實爲獨立的一塊,會單獨換一行;inline元素則先後不會產生換行,一系列inline元素都在一行內顯示,直到該行排滿。
大致來講HTML元素各有其自身的佈局級別(block元素仍是inline元素):
block元素能夠包含block元素和inline元素;但inline元素只能包含inline元素。要注意的是這個是個大概的說法,每一個特定的元素能包含的元素也是特定的,因此具體到個別元素上,這條規律是不適用的。好比 P 元素,只能包含inline元素,而不能包含block元素。
細節對比:
display:block
block元素會獨佔一行,多個block元素會各自新起一行。默認狀況下,block元素寬度自動填滿其父元素寬度。
block元素能夠設置width,height屬性,即便設置了寬度,仍然是獨佔一行。
block元素能夠設置margin和padding屬性。
display:inline
inline元素不會獨佔一行,多個相鄰的行內元素會排列在同一行裏,直到一行排列不下,纔會新換一行,其寬度隨元素的內容而變化。
inline元素設置width,height屬性無效。
inline元素的margin和padding屬性,水平方向的padding-left, padding-right, margin-left, margin-right都產生邊距效果;
但豎直方向的padding-top, padding-bottom, margin-top, margin-bottom不會產生邊距效果。
display:inline-block
簡單來講就是將對象呈現爲inline對象,可是對象的內容做爲block對象呈現。以後的內聯對象會被排列在同一行內。
好比咱們能夠給一個link(a元素)inline-block屬性值,使其既具備block的寬度高度特性又具備inline的同行特性。
margin: auto
:適用於塊級元素
text-align: center
:適用於內聯元素
line-height: height
:適用於內聯元素
The line-height
CSS property sets the height of a line box. It's commonly used to set the distance between lines of text. On block-level elements, it specifies the minimum height of line boxes within the element. On non-replaced inline elements, it specifies the height that is used to calculate line box height.
line-height
CSS 屬性用於設置多行元素的空間量,如多行文本的間距。對於塊級元素,它指定元素行盒(line boxes)的最小高度。對於非替代的 inline 元素,它用於計算行盒(line box)的高度。(也就是說內聯元素的高度就是在父元素中指定的 line-height
了。)
絕對定位負 margin
:適用於塊級元素
父元素:relative;子元素:absolute,margin-top: -(高度的一半); margin-left: -(寬度的一半);
絕對定位 + transform
:適用於塊級元素
See the Pen neg-margin by Li Yiming (@upupming) on CodePen.
絕對定位 + margin: auto
:適用於塊級元素
See the Pen neg-transform by Li Yiming (@upupming) on CodePen.
另外還有:
使用 flex
彈性盒子佈局:塊級元素(兼容性很差)
.parent {
width: 600px;
height: 200px;
border: 1px solid red;
display: flex;
align-items: center; /*垂直居中*/
justify-content: center; /*水平居中*/
}
複製代碼
padding
child 是 parent 的一半:塊級元素
display: table-cell
僞元素
::before
和 ::after
垂直居中:
.parent {
width: 300px;
height: 300px;
border: 1px solid red;
text-align: center;
}
.child {
background: blue;
width: 100px;
height: 40px;
display: inline-block;
vertical-align: middle;
}
.parent::before {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;
}
複製代碼
連接:www.nowcoder.com/questionTer… 來源:牛客網
<article id="electriccars" data-columns="3" data-index-number="12314" data-parent="cars">
...
</article>
複製代碼
JS 訪問利用 .dataset
:
var article = document.querySelector('#electriccars');
article.dataset.columns // "3"
article.dataset.indexNumber // "12314"
article.dataset.parent // "cars"
複製代碼
CSS 訪問利用 attr()
:
article::before {
content: attr(data-parent);
}
/* 屬性選擇器使用 data */
article[data-columns='3'] {
width: 400px;
}
article[data-columns='4'] {
width: 600px;
}
複製代碼
beforeCreate
:vue 實例的掛載元素 el
和數據對象 data
都是 undefined
,尚未初始化。【None】created
:vue 實例的數據對象 data
有了,能夠訪問數據和方法,未掛載到 DOM,el
尚未。【data
】beforeMount
:vue 實例的 el
和 data
都初始化了,可是掛載以前爲虛擬的 DOM 結點。【data
& el
】mounted
:vue 實例掛載到真正的 DOM 上,能夠經過 DOM 獲取 DOM 結點。【data
& el
& DOM】beforeUpdate
:響應式數據更新時調用,發生在虛擬 DOM 打補丁以前,適合在更新以前訪問現有的 DOM,好比手動移除已添加的事件監聽器。【data
& el
& 舊 DOM】updated
:虛擬DOM從新渲染和打補丁以後調用,組成新的DOM已經更新,避免在這個鉤子函數中操做數據,防止死循環。【【data
& el
& 新 DOM】】beforeDestroy
:實例銷燬前調用,實例還能夠用,this能獲取到實例,經常使用於銷燬定時器,解綁事件。destroyed
:實例銷燬後調用,調用後全部事件監聽器會被移除,全部的子實例都會被銷燬。