前端面試梳理(二)

備戰秋招,複習基礎。若有錯誤,歡迎批評指正,共同進步!javascript

寫在最前

整理自本身的面試經驗+網絡資料css

部分資料參考自網絡,在具體內容前均有標出~感恩你們~html

因爲篇幅緣由,拆成兩篇~前端面試梳理(一)前端

JavaScript

this

參考資料:JavaScript 的 this 原理java

參考資料:JS this指向總結ios

在函數體內部,指代函數當前的運行環境。css3

哪一個對象調用函數,函數裏面的this指向哪一個對象。web

  • 普通函數調用:沒特殊意外,就是指向全局對象-window。
let username='cn'
function fn(){
    alert(this.username);//undefined
}
fn();
複製代碼
  • 對象函數調用:哪一個函數調用,this指向哪裏
window.b=2222
let obj={
    a:111,
    fn:function(){
        alert(this.a);//111
        alert(this.b);//undefined
    }
}
obj.fn();
複製代碼
  • 構造函數調用
let TestClass=function(){
    this.name='111';
}
let subClass=new TestClass();
subClass.name='cn';
console.log(subClass.name);//cn
let subClass1=new TestClass();
console.log(subClass1.name)//111
複製代碼
  • apply和call調用:改變傳入函數的this
let obj1={
    a:222
};
let obj2={
    a:111,
    fn:function(){
        alert(this.a);//222
    }
}
obj2.fn.call(obj1)
複製代碼
  • 箭頭函數調用:箭頭函數裏面的 this 是繼承外面的環境
let obj={
    a:222,
    fn:function(){    
        setTimeout(function(){console.log(this.a)})
    }
};
obj.fn();//undefined ← 傳給setTimeout的是普通函數,this 指向是 window 

let obj={
    a:222,
    fn:function(){    
        setTimeout(()=>{console.log(this.a)});
    }
};
obj.fn();//222 ← 傳給setTimeout的是箭頭函數,setTimeout的上層做用域是fn。fn裏面的this指向 obj,因此setTimeout裏面的箭頭函數的this指向obj。
複製代碼

普通函數和箭頭函數的區別

1. 箭頭函數是匿名函數,不能做爲構造函數,不能使用new
2. 箭頭函數不綁定arguments,取而代之用rest參數...解決
3. 箭頭函數不綁定this,會捕獲其所在的上下文的this值,做爲本身的this值
4. 箭頭函數經過call()或apply()方法調用一個函數時,只傳入了一個參數,對this並無影響。
5. 箭頭函數沒有原型屬性
6. 箭頭函數不能當作Generator函數,不能使用yield關鍵字
複製代碼

new的機理

參考資料:js中的new()到底作了些什麼??面試

建立一個新對象,將新對象的_proto_指向構造函數的原型對象,而後將構造函數的this指向新對象。調用構造函數。ajax

1. 建立一個新對象;
2. 將構造函數的做用域賦給新對象(所以 this 就指向了這個新對象) ;
3. 執行構造函數中的代碼(爲這個新對象添加屬性) ;
4. 返回新對象。
複製代碼

閉包

參考資料:完全搞懂JS閉包各類坑

閉包:可以訪問另外一個函數做用域的變量的函數。

function outer() {
     var  a = '變量1'
     var  inner = function () {
            console.info(a)
     }
    return inner    // inner 就是一個閉包函數,由於他可以訪問到outer函數的做用域
}
複製代碼

因爲閉包會攜帶包含它的函數的做用域,由於會比其餘函數佔用更多內容,過分使用閉包,會致使內存佔用過多。

原型鏈 prototype _proto_

參考資料:幫你完全搞懂JS中的prototype、__proto__與constructor(圖解)

1. __proto__和constructor屬性是對象所獨有的;
2. prototype屬性是函數所獨有的,由於函數也是一種對象,因此函數也擁有__proto__和constructor屬性。

3. __proto__屬性的做用就是當訪問一個對象的屬性時,若是該對象內部不存在這個屬性,那麼就會去它的__proto__屬性所指向的那個對象(父對象)裏找,一直找,直到__proto__屬性的終點null,再往上找就至關於在null上取值,會報錯。經過__proto__屬性將對象鏈接起來的這條鏈路即咱們所謂的原型鏈。
4. prototype屬性的做用就是讓該函數所實例化的對象們均可以找到公用的屬性和方法,即f1.__proto__ === Foo.prototype。
5. constructor屬性的含義就是指向該對象的構造函數,全部函數(此時當作對象了)最終的構造函數都指向Function。
複製代碼

原型鏈

js執行機制(宏任務 微任務)

參考資料:這一次,完全弄懂 JavaScript 執行機制

同步和異步的任務

let data = [];
$.ajax({
    url:www.javascript.com,
    data:data,
    success:() => {
        console.log('發送成功!');
    }
})
console.log('代碼執行結束');

1. ajax進入Event Table,註冊回調函數success。
2. 執行console.log('代碼執行結束')。
3. ajax事件完成,回調函數success進入Event Queue。
4. 主線程從Event Queue讀取回調函數success並執行。
複製代碼

macro-task(宏任務):包括總體代碼script,setTimeout,setInterval

micro-task(微任務):Promise,process.nextTick

宏任務和微任務

怎樣讓setTimeOut執行兩次

setTimeout(code,等待毫秒數)
屢次調用: 1 code自身再次調用setTimeout()
           2 用setInterval(code,時間間隔)
複製代碼

經過DOM切換圖片

1. 定義圖片路徑數組存放圖片路徑。定義字符串數組存放文字描述。
2. 封裝prev和next方法
3. 綁定按鈕的點擊事件
複製代碼

自執行函數(當即執行函數)

具體含義待補充!!!

1 var fn1 = function(){
  }();
2 (function (){
  }());
3 (function(){
  }();
 4 !function(){
  }();
 5 +function(){
  }();
複製代碼

相等操做符

  • == 先轉換再比較 bolean → 數值 對象 → valueOf()/toString() 字符串 → 數值
  • === 不轉換直接比較 null===undefined//false
  • object.is(a,b) 比較規則與===相同
比較 == === object.is()
null undefined true false false
NaN NaN false false true
undefined 0 false false false
null 0 false false false
-0 +0 true true false

for-in 和 for-of

  • for...in :以原始插入順序迭代對象的可枚舉屬性
  • for...of:遍歷可迭代對象定義要迭代的數據(非自定義屬性)
Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let arr = ['a','b','c'];
arr.hobby = 'foosball';

for (let i in arr) {                                            ← for in 用鍵key遍歷
  console.log(i); // 0, 1, 2, "hobby", "arrCustom", "objCustom" ← 可循環出自定義的屬性
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); //0, 1, 2, "hobby"                          ← 過濾非實例屬性
  }
}

for (let i of iterable) {                                       ← for of 用值value遍歷
  console.log(i); // 'a', 'b', 'c'                              ←  無自定義屬性
}

for(var key of Object.keys(arr)){                               ← 使用Object.keys()方法獲取對象key的數組
    console.log(arr[key]);
}
複製代碼

檢測數據類型

1. typeof 返回number/boolean/symbol/string/object/undefined/function
2. instanceof 判斷A是否是B的實例
3. constructor [].constructor == Array //true
4. toString Object.prototype.toString.call([]);
其中差別待補充!!!
複製代碼

class繼承和es5繼承

參考資料:ES6中的類繼承和ES5中的繼承模式詳解

ES5的繼承,實質是先創造子類的實例對象this,而後再將父類的方法添加到this上面(Parent.apply(this))。

ES6的繼承機制徹底不一樣,實質是先創造父類的實例對象this(因此必須先調用super方法),而後再用子類的構造函數修改this。

類的繼承能夠看作是寄生組合式繼承的語法糖

使對象屬性不可修改

Object.freeze 操做一個對象後, 就會使這個對象不能夠新增屬性, 刪除屬性, 對於已經存在的屬性也不能夠從新配置(The descriptor for the property), 或者被修改.若是屬性是一個對象值的, 那麼這個屬性仍是能夠被修改的, 除非再次讓這個屬性爲 freeze.

缺陷:freeze 操做只是針對於 window.openApi 對象自己, 而非針對 window 對象自己, 因此你仍舊能夠從新定義 window 的 openApi 屬性.
複製代碼

經過 Object.defineProperty 分別設置其 configurable 和 writable 爲 false.

手寫代碼

實現一個sleep()

<script type="text/javascript">
            //方法一
            function sleep1(ms, callback) {
                setTimeout(callback, ms)
            }
            //sleep 1s
            sleep1(1000, () => {
                console.log(1000)
            })
            //方法二
            function sleep2(ms) {
                return new Promise(function(resolve, reject) {
                    setTimeout(resolve, ms)
                })
            }
            sleep2(1000).then(() => {
                console.log(2000)
            })
            //方法三
            function sleep3(ms) {
                return new Promise(function(resolve, reject) {
                    setTimeout(resolve, ms)
                })
            }
            async function init() {
                await sleep3(1000);
            }
            init().then(() => {
                console.log(3000)
            })
        </script>
複製代碼

用原生js寫splice

參考資料:對js數組的splice實現

Array.prototype.splice = function(start,deleteCount){
 
    var max = Math.max,
        min = Math.min,
        delta,
        element,
        insertCount = max(arguments.length - 2,0),  //插入的元素的個數,最小爲0
        k = 0,
        len = this.length,
        new_len,
        result = [],    //返回的數組,包函了被刪除的元素
        shift_count;
 
    start = start || 0; //如何start不存在,則從0開始
    if(start < 0){
        start += len;   //確保start爲正數
    }
    start = max(min(start,len),0); //確保start爲正數
    deleteCount = max(min(typeof deleteCount === 'number' ? deleteCount : len,len-start),0);    //要刪除元素的個數
    //  1.若是deleteCount存在則deleteCount,不然len
    //  2.用1的結果與len-start對比,取較小者(由於最大可刪除的元素個數爲len-start)
    //  3.用2的結果與0比對,取大者,防止爲負數
    delta = insertCount - deleteCount;     
    alert(delta);
    /*
     * 1.若是delta大於0,說明數組長度會增長
     * 2.若是delat小於0,說明數組長度會減小
     */
    new_len = len + delta;  //數組的新長度
    while(k < deleteCount){      //這個while循環的做用是保存要返回的result,即保存被刪除的元素
        element = this[start + k];
        if(element != undefined){
            result[k] = element;
        }
        k++;
    }
    shift_count = len - start - deleteCount;   
    /*
     * 1. len-start ,start前端的元素不用動
     * 2. 用1的結果再減去deleteCount,是start後面要保留的元素的個數
     * 3. 經過shift_count次的遍歷,就能夠把要保留的元素向前移動,達到刪除的目的
     */
    if(delta <= 0){  //在數組長度減小的狀況下
        k = start + insertCount;    //k的初始下標爲要保留的元素新的開始下標
        while(shift_count){
            this[k] = this[k - delta];  //後面的替換前面的要刪除的元素
            k += 1;
            shift_count -= 1;
        }
        this.length = new_len;
    }else if(delta > 0){ //在數組長度增長的狀況下
        k = 1;
        while(shift_count){
            this[new_len - k] = this[len - k];  //從數組的最後一個元素開始,倒着進行替換
            k += 1;
            shift_count -= 1;
        }
        this.length = new_len;
    }
    for(k = 0; k < insertCount; k+=1){
        this[start + k] = arguments[k+2];       //插入替換元素
    }
    return result;
};
複製代碼

用原生JS寫<div>

var divE = document.createElement('div');
var divId = document.createAttribute("id");
divId.value = 'name';
divE.setAttributeNode(divId); //爲節點添加屬性
複製代碼

給原型添加方法

Object(原型類名).prototype.sss = function(){
    console.log(this);
}
複製代碼

寫一個js繼承

寄生組合式繼承:經過借用構造函數來繼承屬性,經過原型鏈的方式來繼承方法,而不須要爲子類指定原型而調用父類的構造函數,咱們須要拿到的僅僅是父類原型的一個副本。所以能夠經過傳入子類和父類的構造函數做爲參數,首先建立父類原型的一個複本,併爲其添加constrcutor,最後賦給子類的原型。這樣避免了調用兩次父類的構造函數,爲其建立多餘的屬性。

//父:person
function Person(name){
  this.name=name;
}
Person.prototype.sayName=function(){
  console.log(this.name+' '+this.gender+' '+this.age);
}
//借用構造函數來繼承屬性的方法
function inheritPrototype(Female,Person){ 
  var protoType=Object.create(Person.prototype);
  protoType.constructor=Female;
  Female.prototype=protoType;
}
//調用繼承方法
inheritPrototype(Female,Person);
//子:female 新增方法
Female.prototype.sayAge=function(){
    console.log(this.name+' '+this.age);
}
//嘗試調用
var fm=new Female('skila','female',19);
fm.sayName();//skila female 19
fm.sayAge();skila  19
複製代碼

原生Js實現Bind

1. 不會當即執行函數,須要返回一個待執行的函數
2. 做用域綁定,使用apply或者call方法
3. 參數傳遞,因爲參數的不肯定性,用apply傳遞數組
複製代碼
Function.prototype.bind = function(newThis) {
    var aArgs = Array.prototype.slice.call(arguments, 1) //拿到除了newThis以外的預置參數序列
    var that = this
    return function() {
        return that.apply(newThis, aArgs.concat(Array.prototype.slice.call(arguments)))
        //綁定this同時將調用時傳遞的序列和預置序列進行合併
    }
}
複製代碼

手寫一個計時器

<html>
    <head>
        <script type="text/javascript">
            var c=0
            var t
            function timedCount()
              {
                    document.getElementById('txt').value=c
                    c=c+1
                    t=setTimeout("timedCount()",1000)
              }
            function stopCount()
              {
                      clearTimeout(t)
              }
        </script>
    </head>
    <body>
    
    <form>
        <input type="button" value="Start count!" onClick="timedCount()">
        <input type="text" id="txt">
        <input type="button" value="Stop count!" onClick="stopCount()">
    </form>
    
    </body>
</html>
複製代碼

手寫一個深拷貝

function isObj(obj) {
//判斷是否爲對象或者函數,但不是null
    return (typeof obj === 'object' || typeof obj === 'function') && obj !== null
}

function deepCopy(obj) {
    let newObj = Array.isArray(obj) ? [] : {}
    for(let key in obj) {
        newObj[key] = isObj(obj[key]) ? deepCopy(obj[key]) : obj[key]
    }
    return newObj
}
或
函數庫lodash,提供_.cloneDeep()
複製代碼

獲取當前Url中某個參數

function getQuery(name) {
  // 正則:[找尋'&' + 'url參數名字' = '值' + '&']('&'能夠不存在)
    let reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
    let r = window.location.search.substr(1).match(reg);
    if(r != null) {
      // 對參數值進行解碼
        return unescape(r[2]); 
    }
    return null;
}

// 調用方法,注意須要傳入String類型的數據,輸出結果爲String類型
getQuery('id');   // '123'
複製代碼

手寫正則匹配手機號

function isPoneAvailable($poneInput) {
            var myreg=/^[1][3,4,5,7,8][0-9]{9}$/;
            if (!myreg.test($poneInput.val())) {
                return false;
            } else {
                return true;
            }
        }
複製代碼

手寫隨機打亂數組

var arr = [1, 2, 3, 4, 5];
arr.sort(functon() {
    return Math.random() - 0.5;
})
複製代碼

手寫判斷兩個網絡地址是否同一子網

參考資料:javascript判斷兩個IP地址是否在同一個網段的實現思路

要判斷兩個IP地址是否在同一個網段,將它們的IP地址分別與子網掩碼作與運算,獲得的結果爲網絡號,若是網絡號相同,就在同一子網,不然,不在同一子網。

function isEqualIPAddress (addr1,addr2,mask){ 
    if(!addr1 || !addr2 || !mask){ 
        console.log("各參數不能爲空"); 
        return false; 
    } 
    var res1 = [], res2 = []; 
    addr1 = addr1.split("."); 
    addr2 = addr2.split("."); 
    mask = mask.split("."); 
    for(var i = 0,ilen = addr1.length; i < ilen ; i += 1){ 
    res1.push(parseInt(addr1[i]) & parseInt(mask[i])); 
    res2.push(parseInt(addr2[i]) & parseInt(mask[i])); 
    } 
    if(res1.join(".") == res2.join(".")){ 
        console.log("在同一個網段"); 
        return true; 
    }else{ 
        console.log("不在同一個網段"); 
        return false; 
    } 
} 
複製代碼

手寫indexOf

function indexOf(str, val){
    var strLen = str.length, valLen = val.length
    for(var i = 0; i < strLen; i++){
        var matchLen = i + valLen
        var matchStr = str.slice(i, matchLen)
        if(matchLen > strLen){
            return -1
        }
        if(matchStr === val){
            return i
        }
    }
    return -1
}

複製代碼

手寫實現call

Function.prototype.call2 = function (context) {
    var context = Object(context) || window
    context.fn = this
    var args = []
    for (var i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i +']')
    }

    var res = eval('context.fn(' + args + ')')

    delete context.fn
    return res
}
複製代碼

寫ES5擴展類

CSS

盒模型

盒模型:包含了元素內容(content)、內邊距(padding)、邊框(border)、外邊距(margin)幾個要素。

W3C標準盒模型
IE盒模型

隱藏元素

用途:
    1 對文本的隱藏
    2 隱藏超連接
    3 對統計代碼隱藏
    4 隱藏超出的圖片
    5 CSS隱藏滾動條
    6 CSS隱藏div層
方法:
    1 display:none → 不佔位置
    2 overflow:hidden / visibility:hidden
    3 opacity:0
    4 position:absolute;top:-9999px;left:-9999px
複製代碼

水平垂直居中

1. 雙層 - 使用absolute定位居中
    .container{
        position:relative;
        height:100px;  ← 不然無高度,會向上偏移覆蓋上方元素
    }
    .child{
        transform:translate(-50%,-50%);  ← 圖像大小的一半
        top:50%;left:50%;   ← 容器位置的一半
        position:absolute;
    }
2. 雙層 - 使用flexbox居中(主流)
    .container{
        display:flex;
        justify-content:center;
        align-items:center;
    }
3. 雙層 - 使用calc基於當前頁面佈局計算尺寸
    .container{
        position:relative;
        height:100px;  ← 沒設定高度則找不到盒子
        width:100px;  ← 沒設定寬度則默認頁面居中
    }
    .child{  ← 使盒子居中,盒子內部不必定居中!
        position:absolute;
        width:40%;
        height:40%;
        top:calc(50%-20%);
        left:calc(50%-20%);
    }
45. 圖片子元素
    .child{
        display:inline-block; 
        vertical-align:middle; ← 須要有一個兄弟文字元素 設置居中 使圖片和文字的基線對齊
    }
5. 雙層 - margin auto 定位塊級元素 
    .container{
        height: 200px;
        width: 200px;
        position: relative;
    }
    .child{
        margin: auto; ← 必須設定四周位置和寬高
        top: 0px;
        bottom: 0px;
        left: 0px;
        right: 0px;
        height: 100px;
        width: 100px;
        position: absolute;
    }
6. 單層 - 使用text-align水平居中(非垂直居中)
    .container{
        text-align:center;
    }
7. 單層 - 單行文本元素 使用text-align水平居中 + line-height垂直居中
    .div{
        display: inline-block;
        height: 100px;
        line-height: 100px;
        text-align: center;
        width: 200px;  ← 不設寬度的話,寬度自適應爲文字寬度
    }
8. 單層 - 多行文本元素
    .div{
        display:table-cell;
        text-align:center;
        vertical-align: middle;
    }
複製代碼

常見佈局方式

1. 傳統盒模型佈局方式:使用display(文檔流)+position屬性(定位佈局)+float屬性(浮動佈局)
2. flex彈性佈局:display:flex
3. Grid網格佈局:實現二維佈局 display:grid / inline-grid / subgrid
    grid-template-columns 列寬 grid-template-rows 行高 有幾個數字就幾列/行
    grid-column-gap 列與列的距離
4. 聖盃佈局:兩邊定寬,中間自適應。
    三個元素都是float:left
    .left{margin-left:-100%}
    .right{margin-left:-(width)px}
    .mid{padding:width}
5. 雙飛翼佈局:與聖盃相似,只是中間防遮擋不一樣
    在中間的div內部建立子div放置內容,子div裏用margin留出位置
複製代碼

BFC

塊級格式化上文,是一個獨立的佈局環境,其中的元素佈局是不受外界影響。

position:absolute / fixed
或
display: inline-block / table-cell / table / caption
或
float != null / overflow != visible
複製代碼

特性:

1 子元素margin重疊
2 會自動清除內部浮動
複製代碼

防止外邊距重疊解決方案:

1 外層元素padding代替
2 內層元素透明邊框 border:1px solid transparent;
3 內層元素絕對定位 postion:absolute:
4 外層元素 overflow:hidden;
5 內層元素 加float:left;或display:inline-block;
6 內層元素padding:1px;
複製代碼

如何解決子元素形成的父元素高度塌陷問題:

1 給父元素再添加一個高度爲0的子元素,而且讓它清除浮動【clear:both;】
2 給父元素設置display:inline-block;
3 給父元素設置overflow:hidden;
4 給父元素設置固定的高度
5 對父元素使用僞元素:after,而且清除浮動【clear:both;】
複製代碼

尺寸

px:絕對尺寸,不能適用瀏覽器縮放
em:相對尺寸,相對於當前對象內文本的font-size,但須要知道父元素文本的font-size和對象內文本的font-size
rem:相對尺寸,相對於根元素<html>的font-size
複製代碼

margin-left:auto

參考資料:[margin-left: auto;爲何可使的元素靠右](https://segmentfault.com/q/1010000008431088)
複製代碼
div {
  width: 100px;
  margin-left: auto;
}

由於
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' +'border-right-width' + 'margin-right' = width of containing block
因此
margin-left = width of containing block - width(div)
複製代碼

頁面滾動 導航欄固定在頂部

當頁面滾動超出設置距離時,改變樣式屬性 切換定位狀態fixed,給top設置一個值

--- css ---
.box{
	  position: relative;
	  height: 80px;
	  width: 100%;
	  z-index: 999;
	}
.box-active{
  position: fixed;
  top: 0;
}

--- js ---
// 監聽事件
 window.addEventListener('scroll', function(){
 	let t = $('body, html').scrollTop();   // 目前監聽的是整個body的滾動條距離
 	if(t>0){
		$('.box').addClass('box-active')
	}else{
		$('.box').removeClass('box-active')
	}
 })
複製代碼

body自適應瀏覽器高度

document.getElementsByTagName('body')[0].style.height = window.innerHeight+'px';
複製代碼
html{
    height:100%
    }
body{
   height:100%;
}
複製代碼

爲body設置高度,只是IE6下有做用。而代碼中除了給body應用之外,還給html對象也應用了相同的樣式。這樣作的好處是使IE與Firefox都可以實現高度自適應。另外,FirefoxFirefox中的HTML標籤不是100%高度,所以給兩個標籤都定義爲height:100%;以保證兩個瀏覽器下均可以正常顯示。

分欄高度相等

無論中間內容怎麼撐高,兩邊側欄都會跟着等高

<style>
            body{margin: 0;padding: 0;}
            .wrap{
                overflow: hidden;  ← 必須的,不然會顯示溢出的內容!
            }
            .left{
                width: 200px;
                background-color: #C5C5C5;
                float: left;
                margin-bottom: -3000px;
                padding-bottom: 3000px;
            }
            .right{
                width: 300px;
                background-color: yellow;
                float: right;
                margin-bottom: -3000px;   ← 使父級寬度不被撐開成3000px
                padding-bottom: 3000px;
            }
            .main{
                height: 500px;
                background-color: lightpink;
                margin: 0 310px 0 210px ;
            }
        </style>
複製代碼

畫橢圓

<div class="ellipse"></div>
<style>
.ellipse {
  width: 400px;
  height: 200px;
  border-radius: 50%;
  background-color: #000;
}
</style>
複製代碼
<svg width="800" height="400">
    <ellipse rx="200" ry="100" cx="400" cy="200"></ellipse>
</svg>
複製代碼
<svg width="800" height="400" id="J_SvgWrap"></svg>
<script>
var svg = document.getElementById('J_SvgWrap');
var ell = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');
ell.setAttribute("cx", 400);
ell.setAttribute("cy", 200);
ell.setAttribute("rx", 200)
ell.setAttribute("ry", 100)
svg.appendChild(ell);
</script>
複製代碼
<canvas width="800" height="400" id="J_MyCanvas"></canvas>
<script>
var cvs = document.getElementById('J_MyCanvas');
var ctx = cvs.getContext('2d');
 
ctx.scale(1, 0.5);
ctx.arc(400, 200, 200, 0, Math.PI * 2);
ctx.fill();
</script>
複製代碼

CSS3新屬性

1. 邊框 border-radius box-shadow border-image
2. 背景 background-size background-origin
3. 文本效果 text-shadow word-wrap
4. 字體:CSS3 @font-face 規則能夠自定義字體。
5. 2D 轉換(transform)
6. 3D 轉換
7. transition:過渡效果,使頁面變化更平滑
8. animation:動畫
複製代碼

HTML

Xhtml和html的區別

XHTML 元素必須被正確地嵌套。
XHTML 元素必須被關閉。
標籤名必須用小寫字母。
XHTML 文檔必須擁有根元素。
複製代碼

React

寫一下向子組件傳狀態

父:
this.state = {name:'xx'}
<Person data = {this.state.name}/>
子:
<div data = {this.porps.name}/>
複製代碼

基礎筆記梳理 - React

Vue

基礎筆記梳理 - Vue

框架對比

參考資料:Vue.js與React的全面對比

對比點 框架 區別
數據流
- Angular 雙向綁定。界面操做實時反映到數據,數據變動實時展示到頁面
- Vue 默認單向綁定,經過依賴追蹤支持雙向綁定:經過 Object.defineProperty 把data對象的屬性所有轉爲 getter/setter
- React 函數式編程,單向數據流:在View層直接寫JS代碼Model層中的數據拿過來渲染
視圖渲染
- Angular 在DOM加載後遍歷生成NG指令
- Vue 使用真實DOM做爲模板,數據綁定到真實節點,改變多少更新多少
- React 渲染虛擬DOM,再給真實DOM打補丁。超大量數據的首屏渲染有優點
事件綁定
- html onclick =" listen() ";
- Vue @click = " listen($event,參數) ";
- React onClick={this.deleteRow.bind(this, id) 或 onClick={(e) => this.deleteRow(id, e)
數據獲取
- 原生js var xhr = creatXHR();
- Vue axios.get(url).then(function(response){...}).catch(function(error){...});
- React axios/reqwest
路由
- Vue <router-link to="/foo">Go to Foo</router-link>
- React <Route path="/repos" component={Repos}/>
開發模式
- Vue Vue是MVVM模式的一種方式實現
- React React自己,是嚴格的view層,MVC模式

待補充……!!!

H5

H5是一個解決方案,是一系列技術的集合

H5主要技術

1 頁面預加載:使用createJS中的preloadJS
2 音樂加載播放:使用createJS中的soundJS
3 可滑動頁面:swiper.js插件,touch系列事件
4 可塗抹擦除:使用canvas疊加層
5 動態文字和圖片:css3動畫和Js動畫
6 可填表報名
7 分享自定義文案和圖片:使用微信jssdk
8 包含:audio標籤、canvas拖拽特性、本地存儲、websocket通信、盒模型、絕對定位
複製代碼

移動H5自適應佈局

1 分辨率resolution適配:使用rem。針對不一樣屏幕寬度,調整高寬比、文字大小、元素間距
2 單位英寸像素數PPI適配:標題用rem(會發虛),段落用px,用media query或Js適配
3 設備像素比例DPR適配複製代碼
相關文章
相關標籤/搜索