【前端面試】同學(xué),你會(huì)手寫代碼嗎?
(給前端大學(xué)加星標(biāo),提升前端技能.)
【前端面試】?手寫代碼匯總:CSS & JS作者:我不吃餅干呀
https://juejin.im/post/5c9edb066fb9a05e267026dc
如果您發(fā)現(xiàn)錯(cuò)誤,請(qǐng)一定要告訴我,拯救一個(gè)辣雞(但很帥)的少年就靠您了!
CSS 部分
兩欄布局
要求:垂直兩欄,左邊固定右邊自適應(yīng)。
Document .outer {height: 100px;margin-bottom: 10px;}.left {background: tomato;height: 100px;}.right {background: gold;height: 100px;}/* 浮動(dòng) */.outer1 .left {width: 200px;float: left;}.outer1 .right {width: auto;margin-left: 200px;}/* flex */.outer2 {display: flex;}.outer2 .left {flex-grow: 0;flex-shrink: 0;flex-basis: 200px;}.outer2 .right {flex: auto; /* 1 1 auto */}/* position */.outer3 {position: relative;}.outer3 .left {position: absolute;width: 200px;}.outer3 .right {margin-left: 200px;}/* position again */.outer4 {position: relative;}.outer4 .left {width: 200px;}.outer4 .right {position: absolute;top: 0;left: 200px;right: 0;}1-left1-right2-left2-right3-left3-right4-left4-right
三欄布局
要求:垂直三欄布局,左右兩欄寬度固定,中間自適應(yīng)
Document .outer, .left, .middle, .right {height: 100px;margin-bottom: 5px;}.left {background: tomato;}.middle {background: lightgreen;}.right {background: gold;}/* 左右分別設(shè)置絕對(duì)定位 中間設(shè)置外邊距 */.outer1 {position: relative;}.outer1 .left {position: absolute;width: 100px;}.outer1 .middle {margin: 0 200px 0 100px;}.outer1 .right {position: absolute;width: 200px;top: 0;right: 0;}/* flex 布局 */.outer2 {display: flex;}.outer2 .left {flex: 0 0 100px;}.outer2 .middle {flex: auto;}.outer2 .right {flex: 0 0 200px;}/* 浮動(dòng)布局 但是 html 中 middle要放到最后 */.outer3 .left {float: left;width: 100px;}.outer3 .right {float: right;width: 200px;}.outer3 .middle {margin: 0 200px 0 100px;}1-left1-middle1-right2-left2-middle2-right3-left3-right3-middle
圣杯布局 和 雙飛翼布局
和三欄布局要求相同,不過中間列要寫在前面保證優(yōu)先渲染。
Document .outer, .left, .middle, .right {height: 100px;margin-bottom: 5px;}.left {background: tomato;}.middle {background: lightgreen;}.right {background: gold;}/* 圣杯布局 通過浮動(dòng)和負(fù)邊距實(shí)現(xiàn) */.outer1 {padding: 0 200px 0 100px;}.outer1 .middle {width: 100%;float: left;}.outer1 .left {width: 100px;float: left;margin-left: -100%;position: relative;left: -100px;}.outer1 .right {width: 200px;float: left;margin-left: -200px;position: relative;left: 200px;}/* 雙飛翼布局 */.outer2 .middle-wrapper {width: 100%;float: left;}.outer2 .middle {margin: 0 200px 0 100px;}.outer2 .left {width: 100px;float: left;margin-left: -100%;}.outer2 .right {width: 200px;float: left;margin-left: -200px;}圣杯-middle圣杯-left圣杯-right雙飛翼布局-middle雙飛翼布局-left雙飛翼布局-right
三角形
實(shí)現(xiàn)一個(gè)三角形
常見題目,通過 border 實(shí)現(xiàn)
三角形 .box1, .box2, .box3, .box4 {height: 0px;width: 0px;float: left;border-style: solid;margin: 10px;}.box1 { /* 等腰直角 */border-width: 100px;border-color: tomato transparent transparent transparent;}.box2 { /* 等邊 */border-width: 100px 173px;border-color: transparent tomato transparent transparent;}.box3 { /* 等腰 */border-width: 100px 80px;border-color: transparent transparent tomato transparent;}.box4 { /* 其他 */border-width: 100px 90px 80px 70px;border-color: transparent transparent transparent tomato;}
正方形
使用 css 實(shí)現(xiàn)一個(gè)寬高自適應(yīng)的正方形
/* 都是像對(duì)于屏幕寬度的比例 */.square1 {width: 10%;height: 10vw;background: red;}/* margin/padding 百分比是相對(duì)父元素 width 的 */.square2 {width: 20%;height: 0;padding-top: 20%;background: orange;}/* 通過子元素 margin */.square3 {width: 30%;overflow: hidden; /* 觸發(fā) BFC */background: yellow;}.square3::after {content: '';display: block;margin-top: 100%; /* 高度相對(duì)于 square3 的 width */}
扇形
實(shí)現(xiàn)一個(gè) 1/4 圓、任意弧度的扇形
有多種實(shí)現(xiàn)方法,這里選幾種簡(jiǎn)單方法(我看得懂的)實(shí)現(xiàn)。
Document /* 通過 border 和 border-radius 實(shí)現(xiàn) 1/4 圓 */.sector1 {height: 0;width: 0;border: 100px solid;border-radius: 50%;border-color: turquoise tomato tan thistle;}/* 類似三角形的做法加上父元素 overflow: hidden; 也可以實(shí)現(xiàn)任意弧度圓 */.sector2 {height: 100px;width: 200px;border-radius: 100px 100px 0 0;overflow: hidden;}.sector2::after {content: '';display: block;height: 0;width: 0;border-style: solid;border-width: 100px 58px 0;border-color: tomato transparent;transform: translate(42px,0);}/* 通過子元素 rotateZ 和父元素 overflow: hidden 實(shí)現(xiàn)任意弧度扇形(此處是60°) */.sector3 {height: 100px;width: 100px;border-top-right-radius: 100px;overflow: hidden;/* background: gold; */}.sector3::after {content: '';display: block;height: 100px;width: 100px;background: tomato;transform: rotateZ(-30deg);transform-origin: left bottom;}/* 通過 skewY 實(shí)現(xiàn)一個(gè)60°的扇形 */.sector4 {height: 100px;width: 100px;border-top-right-radius: 100px;overflow: hidden;}.sector4::after {content: '';display: block;height: 100px;width: 100px;background: tomato;transform: skewY(-30deg);transform-origin: left bottom;}/* 通過漸變?cè)O(shè)置60°扇形 */.sector5 {height: 200px;width: 200px;background: tomato;border-radius: 50%;background-image: linear-gradient(150deg, transparent 50%, #fff 50%),linear-gradient(90deg, #fff 50%, transparent 50%);}
水平垂直居中
實(shí)現(xiàn)子元素的水平垂直居中
水平垂直居中 .outer {height: 200px;width: 200px;background: tomato;margin: 10px;float: left;position: relative;}.inner {height: 100px;width: 100px;background: black;}/** 通過 position 和 margin 居中* 缺點(diǎn):需要知道 inner 的長(zhǎng)寬*/.inner1 {position: absolute;top: 50%;left: 50%;margin-top: -50px;margin-left: -50px;}/** 通過 position 和 margin 居中 (2*/.inner2 {position: absolute;top: 0;right: 0;bottom: 0;left: 0;margin: auto;}/** 通過 flex 進(jìn)行居中*/.outer3 {display: flex;justify-content: center;align-items: center;}/*** 通過 position 和 transform 居中*/.inner4 {top: 50%;left: 50%;transform: translate(-50%,-50%);position: absolute;}
清除浮動(dòng)
要求:清除浮動(dòng)
可以通過 clear:both 或 BFC 實(shí)現(xiàn)
清除浮動(dòng) .outer {width: 200px;background: tomato;margin: 10px;position: relative;}.inner {height: 100px;width: 100px;background: pink;margin: 10px;float: left;}/* 偽元素 */.outer1::after {content: '';display: block;clear: both;}/* 創(chuàng)建 BFC */.outer2 {overflow: hidden;}
彈出框
使用 CSS 寫一個(gè)彈出框效果
Document .bg {height: 666px;width: 100%;font-size: 60px;text-align: center;}.dialog {z-index: 999;position: fixed;top: 0;right: 0;bottom: 0;left: 0;background: rgba(0, 0, 0, 0.5);}.dialog .content {min-height: 300px;width: 600px;background: #fff;border-radius: 5px;border: 1px solid #ebeef5;box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}頁(yè)面內(nèi)容彈出框
導(dǎo)航欄
要求:一個(gè)
div內(nèi)部放很多水平div,并可以橫向滾動(dòng)。
Document body,html {margin: 0;padding: 0;}/* flex 實(shí)現(xiàn) *//* .nav {display: flex;height: 30px;border: 1px solid #000;padding: 3px;overflow-x: auto;}.nav::-webkit-scrollbar {display: none;}.item {flex: 0 0 200px;height: 30px;margin-right: 5px;background: gray;} *//* inline-block 和 white-space: nowrap; 實(shí)現(xiàn) */.nav {height: 30px;padding: 3px;border: 1px solid #000;overflow-x: auto;white-space: nowrap;}.nav::-webkit-scrollbar {display: none;}.item {display: inline-block;width: 200px;height: 30px;margin-right: 5px;background: gray;}
CSS 部分完,總結(jié),F(xiàn)lex 無(wú)敵。
JavaScript 部分
手寫 bind、call 和 apply
Function.prototype.bind = function(context, ...bindArgs) {// func 為調(diào)用 bind 的原函數(shù)const func = this;context = context || window;if (typeof func !== 'function') {throw new TypeError('Bind must be called on a function');}// bind 返回一個(gè)綁定 this 的函數(shù)return function(...callArgs) {let args = bindArgs.concat(callArgs);if (this instanceof func) {// 意味著是通過 new 調(diào)用的 而 new 的優(yōu)先級(jí)高于 bindreturn new func(...args);}return func.call(context, ...args);}}// 通過隱式綁定實(shí)現(xiàn)Function.prototype.call = function(context, ...args) {context = context || window;context.func = this;if (typeof context.func !== 'function') {throw new TypeError('call must be called on a function');}let res = context.func(...args);delete context.func;return res;}Function.prototype.apply = function(context, args) {context = context || window;context.func = this;if (typeof context.func !== 'function') {throw new TypeError('apply must be called on a function');}let res = context.func(...args);delete context.func;return res;}
實(shí)現(xiàn)一個(gè)繼承
// 參考 You Dont Know JavaScript 上卷// 基類function Base() {}// 派生類function Derived() {Base.call(this);}// 將派生類的原型的原型鏈掛在基類的原型上Object.setPrototypeOf(Derived.prototype, Base.prototype);
實(shí)現(xiàn)一個(gè) new
// 手動(dòng)實(shí)現(xiàn)一個(gè) new 關(guān)鍵字的功能的函數(shù) _new(fun, args) --> new fun(args)function _new(fun, ...args) {if (typeof fun !== 'function') {return new Error('參數(shù)必須是一個(gè)函數(shù)');}let obj = Object.create(fun.prototype);let res = fun.call(obj, ...args);if (res !== null && (typeof res === 'object' || typeof res === 'function')) {return res;}return obj;}
實(shí)現(xiàn)一個(gè) instanceof
// a instanceof bfunction _instanceof(a, b) {while (a) {if (a.__proto__ === b.prototype) return true;a = a.__proto__;}return false;}
手寫 jsonp 的實(shí)現(xiàn)
// foo 函數(shù)將會(huì)被調(diào)用 傳入后臺(tái)返回的數(shù)據(jù)function foo(data) {console.log('通過jsonp獲取后臺(tái)數(shù)據(jù):', data);document.getElementById('data').innerHTML = data;}/*** 通過手動(dòng)創(chuàng)建一個(gè) script 標(biāo)簽發(fā)送一個(gè) get 請(qǐng)求* 并利用瀏覽器對(duì)
