Front end interview factory handwritten source code series (1)

Time:2020-8-2

Nowadays, the requirements of the front-end siege lion are higher and higher, and the common API can not meet the rapid development of the front-end. Now, most companies will ask the interviewers to write down the principle of common API in front end to prove your understanding of the knowledge point. Next, I will list the common handwritten principle questions in my interview and in CSS and JS parts that I think are more important! Please look forward to sharing the handwritten schematic diagram of Vue family bucket and react family barrel!

Front end interview factory handwritten source code series (1)

JS part

Handwritten native Ajax

Usually, in the project development, AJAX will be used to request the back-end interface to obtain data in the front-end rendering effect. At present, there are many encapsulated Ajax request libraries on the market, such as: jQuery version of Ajax, Axios request Library Based on promise, flyio and so on. At present, many people can only use these APIs, but today’s interview is often asked: do you understand the principle of Ajax? Do you know how to implement native Ajax? … next, I’ll encapsulate a complete native Ajax.

A complete Ajax request generally includes the following steps:

  • Instantiate XMLHttpRequest object
  • Connecting to the server
  • Send request
  • introduce
function ajax(options) {
  let method =  options.method  ||'get', // if not, the default is get request
      params =  options.params , // parameters carried by get request
      data   =  options.data , // parameters passed by post request
      url    = options.url + (params ? '?' + Object.keys(params).map(key => key + '=' + params[key]).join('&') : ''),
      async  = options.async === false ? false : true,
      success = options.success,
      headers = options.headers;

  let xhr;
  //Create XHR object
  if(window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
  }

  xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 200) {
      success && success(xhr.responseText);
    }
  }

  xhr.open(method, url, async);
  
  if(headers) {
    Object.keys(Headers).forEach(key => xhr.setRequestHeader(key, headers[key]))
  }

  method === 'GET' ? xhr.send() : xhr.send(data)
}

be careful: IE5 and 6 are not compatible with XMLHttpRequest, so you should use the activexobject() object and pass in the Microsoft.XMLHTTP , to achieve the purpose of compatibility.

  • Five states of readyState

    0 – (uninitialized) the send() method has not been called

    1 – (load) sent() method called, sending request

    2 – (load complete) send() method is completed and all response contents have been received

    3 – (interaction) parsing response content

    4 – (complete) the response content is parsed and can be called at the client

Handwriting anti shake and throttling

Nowadays, the effect of front-end interface is more and more complex, and some frequent operations will lead to low page performance and user experience. For example: input box search will frequently adjust the port interface, enlarge and shrink the window, etc.

Anti shake – debounce when the event is triggered continuously and there is no event triggered again within a certain period of time, the event handling function will be executed once. If the event is triggered again before the set time, the delay will start again.

const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

Throttle – throttle when an event is triggered continuously, the event handler is called only once in a certain period of time.

const throttle = (fn, delay = 500) => {
  let flag = true;
  return (...args) => {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, args);
      flag = true;
    }, delay);
  };
};

Implementation principle of handwritten jsonp

function jsonp({url, params, cb}) { 
   return new Promise((resolve, reject) => {
     Window [CB] = function (data) {// declare global variables
        resolve(data)
        document.body.removeChild(script)
      }
      params = {...params, cb}
      let arrs = []
      for(let key in params) {
         arrs.push(`${key}=${params[key]}`)
      }
      let script = document.createElement('script')
      script.src = `${url}?${arrs.join('&')}`
      document.body.appendChild(script)
   })
}

Disadvantages of jsonp

  1. Only get requests can be sent. Post put delete is not supported
  2. Unsafe XSS attack

The principle of handwritten apply

applyThe implementation principle andcallThe implementation principle of is similar, but the parameter form is different. —Array

Function.prototype.apply = function(content = window) {
    content.fn = this;
    let result;
    //Determine if there is a second parameter
    if(arguments[1]) {
        result = content.fn(...arguments[1]);
    } else {
        result = content.fn();
    }
    delete content.fn;
    return result;
}

be careful: when the first parameter passed in by apply is null, this in the function body will point to window.

The principle of handwritten bind

The bind method creates a new function. When the new function is called, the first parameter of bind() will be the this of its runtime, and the subsequent sequence of parameters will be passed in as its parameters before the arguments passed.

Function.prototype.bind = function(content) {
   if(typeof this != 'function') {
      throw Error('not a function');
   }
   let _this = this;
   let args = [...arguments].slice(1);
   return function F() {
      //Determine whether it is used as a constructor
      if(this instanceof F) {
         return _this.apply(this, args.concat([...arguments]))
      }
      return _this.apply(content, args.concat([...arguments]))
   }
}

The principle of handwritten call

Call syntax: fun.call (thisArg, arg1, arg2, arg3, …..)

callThe core principle of

  • Make a function an attribute of an object
  • Execute and delete this function
  • Specify this to the function and pass in the given parameter to execute the function
  • If no parameter is passed, it points to window by default
Function.prototype.call2 = function(content = window) {
    //Determine whether it is under fine and null
    // if(typeof content === 'undefined' || typeof content === null){
    //     content = window
    // }
    content.fn = this;
    let args = [...arguments].slice(1);
    let result = content.fn(...args);
    delete content.fn;
    return result;
}

be careful: when the first parameter passed in by call is null, this in the function body will point to window.

The principle of handwritten NEW

The specific implementation steps of a new operator are as follows:

  • First, the function takes an indefinite number of parameters. The first parameter is the constructor, and the next parameter is used by the constructor
  • Then create an empty object obj internally
  • Because obj objects need to access the properties on the constructor prototype chain, we link the two through setprototypeof. This code is equivalent to obj__ proto__ = Con.prototype
  • Bind obj to the constructor and pass in the remaining parameters
  • Judge whether the value returned by the constructor is an object. If it is, use the value returned by the constructor, otherwise use obj. In this way, the original value returned by the constructor is ignored
/**
 *Create a new operator
 *@ param {*} con constructor
 *@ param {... Any} args forgets the parameters passed in the constructor
 */
  function createNew(Con, ...args) {
    Let obj = {} // creates an object because the new operator returns an object
    Object.setPrototypeOf (obj,  Con.prototype )// link the object to the constructor prototype
    // obj.__ proto__  = Con.prototype  //Equivalent to the above
    let result =  Con.apply (obj, args) // point this in the constructor to this object and pass the parameter
    return result instanceof Object ? result : obj
}

be careful

1、 Several functions of the new operator:

  1. The new operator returns an object, so we need to create an object internally
  2. This object, which is this in the constructor, can access any property mounted on this
  3. This object can access the properties on the constructor prototype chain, so you need to link the object to the constructor
  4. The returned original value needs to be ignored, and the returned object needs to be handled normally

2、 The characteristics of the new operator are as follows

  1. New creates and processes the instance through the constructor test, which can access the properties in the constructor and the properties on the prototype chain of the constructor. Therefore, through the new operator, the instance and the constructor are connected through the prototype chain
  2. If the constructor returns the original value, the return value is meaningless
  3. If the constructor returns an object, the return value will be used normally, causing the new operator to have no effect

Implementation principle of handwritten instanceof

Instanceof is used to detect whether an object has a prototype attribute of a constructor in its prototype chain

function instanceOf(left,right) {
    let proto = left.__proto__;
    let prototype = right.prototype
    while(true) {
        if(proto === null) return false
        if(proto === prototype) return true
        proto = proto.__proto__;
    }
}

Handwritten promise a + specification

At the advanced front end of the interview. It is required that the source code of promise a + specification be handwritten. If you want to know more, please refer to the step-by-step teaching you to realize the full version of promise / A +

class Promise {
    constructor(executor) {
        this.status  ='pending' // initialization status
        this.value  =Undefined // the value returned after successful initialization
        this.reason  =Undefined // reason for initialization failure

        //Solve the problem of handling asynchronous resolve
        this.onResolvedCallbacks  =[] // save all successful resolve
        this.onRejectedCallbacks  =[] // save all failed rejections

        /**
         *@ param {*} value returned value successfully
         *Define the resolve method
         *Note: the status can only be from pending > fulfilled and pending > rejected
         */
        const resolve = (value) => { 
            if(this.status === 'pending') {
                this.status  ='fulfilled' // the status will be converted to the successful state when successful
                this.value  =Value // assign the value returned successfully to promise
                //In order to solve asynchronous resolve and return multi-level promise
                this.onResolvedCallbacks.forEach(fn => {
                    Fn() // when the status changes to success, all resolve functions are executed in turn
                })
            }
        }
        const reject = (reason) => {
            if(this.status === 'pending') {
                this.status  ='rejected '// in case of failure, the status will be converted to the successful state, and the failed state will be rejected
                this.reason  =Reason // assign the return reason of failure to promise
                this.onRejectedCallbacks.forEach(fn => {
                    Fn() // when the state changes to failure state, all reject functions are executed in turn
                })
            }
        }
        Executor (resolve, reject) // executes the callback function passed by promise
    }
    /**
     *Then method of defining promise 
     *@ param {*} onfulfilled successful callback
     *@ param {*} onrejected callback
     */
    then(onFulfilled, onRejected) {
        //In order to solve the problem that the then method returns promise
        const promise2 = new Promise((resolve, reject) => {
            If ( this.status  ==='fulfilled') {// if the status is full, the value is passed to the successful callback
                setTimeout(() => {
                    const x = onFulfilled( this.value )// the value of X may be promise | 123 |'123 '... "
                    //Note: there is no return value when calling PROMISE2 at this time. Use setTimeout to simulate entering the second event loop; the chicken first has the egg
                    resolvePromise(promise2, x, resolve, reject) 
                }, 0)
            }
            if(this.status === 'rejected') {
                setTimeout(() => {
                    const x = onRejected( this.reason )// if the status is rejected, the reason of the video is passed to the failed callback
                    resolvePromise(promise2, x, resolve, reject) 
                }, 0)
            }
            If ( this.status  ==='pending') {// record - ', solve asynchronous
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject) 
                    }, 0)
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        const x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject) 
                    }, 0)
                })
            }
        })
        // return multiple chain calls to solve the problem
    }
}

const resolvePromise = (promise2, x, resolve, reject) => {
    // console.log(promise2, x, resolve, reject)
    If (PROMISE2 = = = x) {// if the returned value is the same as the value returned by the then method
        Throw typeerror ('circular reference ')
    }
    //Judge whether x is promise or not; note: null typeof is also an object to exclude
    if(typeof x === 'function' || (typeof x === 'object' && x !== null)) {
        try {
            Const then = x.then // get the then method on the return value X. note that the method will report an error to catch an exception; reason 111
            If (type of then = = ='function ') {// is considered promise
                then.call(x, y => {
                    // resolve(y)
                    //Recursive parsing; it is possible to return multiple nested promises
                    resolvePromise(promise2, y, resolve, reject)
                }, r => {
                    reject(r)
                })
            }
        } catch(e) {
            reject(e)
        }
    } else {
        resolve(x);
    }
}
module.exports = Promise;

Handwritten JS depth copy

Object depth copy, is one of the common interview questions.

Original object:

let obj = {
   a: 100,
   b: [100, 200, 300],
   c: {
      x: 10
   },
   d: /^\d+$/
}

Shallow cloning

Shallow clones only clone the first layer

Method 1

let obj2 = {...obj};

Method 2

let obj2 = {};
for(let key in obj) {
   if(!obj.hasOwnProperty(key)) break;
   obj2[key] = obj[key];
}

Deep cloning

be careful: in function, date, regular expression, JSON.stringify Will be converted to object {}

Method 1

let obj3 = JSON.parse(JSON.stringify(obj));

Method 2

function deepClone(obj) {
    //Filter some special cases
    if(obj === null) return null;
    if(typeof obj !== "object") return obj;
    If (obj instance of regexp) {// regular
         return new RegExp(obj);
    }
    If (obj instanceof date) {// date
         return new Date(obj);
    }
    // let newObj = {}
    // let newObj = new Object()
    let newObj = new  obj.constructor ; // the purpose of not directly creating an empty object: clone the result of the clone and maintain the previous class = >, that is, you can clone both the common object and an instance object
    for(let key in obj) {
        if(obj.hasOwnProperty(key)) {
             newObj[key] = deepClone(obj[key]);
        }
    }
    return newObj;
}

Usage and common application of symbol

//Symbol basic data type string number Boolean null undefined
//Symbol object data type object

//Characteristics: unique, never equal
Let S1 = symbol ('tmc '); // generally, only number or string is used as the identifier in symbol; otherwise, symbol ([object object]) is returned
let s2 = Symbol();
console.log(s1 === s2)

let obj = {
    [s1]: 1,
    a: 2
}
//The declared symbol property is non enumerable. For - in can traverse its own properties and the properties on the prototype
for(let key in obj) {
    console.log(obj[key])
}
//Gets the property on the object
console.log(Object.getOwnPropertySymbols(obj));

let s3 = Symbol.for('tmc');
let s4 = Symbol.for('tmc');
console.log(s3 === s4);
//Get the key value through symbol
console.log(Symbol.keyFor(s3))

//Symbol built-in objects
// Symbol.iterator  Implement object traversal
//Metaprogramming can modify the operation of native JS
let instance = {
    [Symbol.hasInstance](value) {
        return 'a' in value;
    }
};
console.log({a: 3} instanceof instance)

let arr = [1, 2, 3];
arr[ Symbol.isConcatSpreadable ]= false; // do not expand when splicing arrays
console.log([].concat(arr, [1, 2, 3]));

//Match split search method
let obj1 = {
    [Symbol.match](value) {
        return value.length === 3;
    }
}
console.log('abc'.match(obj1));

//Categories derived objects
class MyArray extends Array {
    constructor(...args) {
        super(...args)
    }
    //Force a change
    static get [Symbol.species]() {
        return Array
    }
}
let v = new MyArray(1, 2, 3);
Let C = v.map (item = > item * = 2); // C is a derivative of V
console.log(c instanceof MyArray)

// Symbol.toPrimitive
//Data type conversion
let obj3 = {
    [Symbol.toPrimitive](type) {
        console.log(type)
        return 123
    }
}
console.log(obj++)

// Symbol.toStringTag
let obj5 = {
    [Symbol.toStringTag]: 'xxxx'
}

console.log(Object.prototype.toString.call(obj5));

Function Coriolis

Currying is a technique that transforms a function that takes multiple parameters into a function that takes a single parameter (the first parameter of the original function), and returns a new function that accepts the remaining parameters and returns the result

//General Edition
function curry(fn, args) {
    var length = fn.length;
    var args = args || [];
    return function() {
        newArgs = args.concat(Array.prototype.slice.call(arguments))
        console.log(newArgs)
        if(newArgs.length < length) {
            return curry.call(this, fn, newArgs);
        } else {
            return fn.apply(this, newArgs);
        }
    }
}
function multiFn(a, b, c) {
    console.log(a * b * c)
    return a * b * c;
}

var multi = curry(multiFn);
multi(2)(3)(4);
// multi(2, 3, 4)
// multi(2)(3, 4)
// multi(2, 3)(4)

be carefulThe main functions and characteristics of function coritization are parameter reuse, early return and delayed execution.

JS array

duplicate removal

Common items

let arr2 = [1, 2, 3, 2, 33, 55, 66, 3, 55];

First:

let newArr = [];
   arr2.forEach(item => {
       if(newArr.indexOf(item) == '-1') {
           newArr.push(item);
       }
   })
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]

The second type:

let newArr = [...new Set(arr2)];
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]

be careful: Array.from (), filter (), for () and other methods can complete the above array de duplication.

Object item

let arr1 = [
    {ID: 1, name: 'Tang Xiaomeng'},
    {ID: 2, name: 'Shi Xiaoming'},
    {ID: 3, name: 'front end development'},
    {ID: 1, name: 'web front end'}
];

Implementation method:

const unique = (arr, key) => {
    return [...new Map(arr.map(item => [item[key], item])).values()]
}
console.log(unique(arr1, 'id'));

// [
    {ID: 1, name: "web front end"},
    {ID: 2, name: "Shi Xiaoming"},
    {ID: 3, name: "front end development"}
]

merge

let arr3 = ['a', 'b']
let arr4 = ['c', 'd']

Method 1ES5

let arr5 = arr3.concat(arr4);
console.log(arr5);

// ['a', 'b', 'c', 'd']

Method 1ES6

let arr6 = [...arr3, ...arr4];
console.log(arr6);

// ['a', 'b', 'c', 'd']

Flattening

let arr7 = [1, 2, [3, 4], [5, 6, [7, 8, 9]]];

First:

let arrNew = arr7.flat(Infinity);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

The second type:

let arrNew = arr7.join().split(',').map(Number);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

The third kind:

let arrNew = arr7.toString().split(',').map(Number);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

The fourth kind:

const flattern = (arr) => {
     const result = []
     arr.forEach((item) => {
         if (Array.isArray(item)) {
              result.push(...flattern(item))
         } else {
              result.push(item)
         }
    })
    return result
}
flattern(arr7);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

Is it an array

let arr = []

First:instanceof

console.log(arr instanceof Array)

The second type:constructor

console.log(arr.constructor === Array)

The third kind:Some methods of judging whether an object has an array such as push

console.log(!!arr.push && !!arr.concat)

The fourth kind: toString

console.log(Object.prototype.toString.call(arr) === '[object Array]')

The fifth type:Array.isArray

console.log(Array.isArray(arr))

be carefulThe fifth way is the best~

CSS part

triangle

The principle of drawing a triangle is to use the border attribute and transparent to complete. Now I’ll list some common triangle implementations.

Isosceles right angle

CSS part

.box1 {
   border-width: 100px;
   border-color: transparent tomato transparent transparent;
}

HTML section

<div class="box1"></div>

design sketch:

Front end interview factory handwritten source code series (1)

Equilateral

CSS part

.box2 {
   border-width: 100px 173px;
   border-color: transparent transparent tomato transparent;
}

HTML section

<div class="box2"></div>

design sketch:

Front end interview factory handwritten source code series (1)

Isosceles

CSS part

.box3 {
   border-width: 100px 80px;
   border-color: transparent transparent tomato transparent;
}

HTML section

<div class="box3"></div>

design sketch:

Front end interview factory handwritten source code series (1)

other

CSS part

.box4 {
   border-width: 100px 90px 80px 70px;
   border-color: transparent transparent transparent tomato;
}

HTML section

<div class="box4"></div>

design sketch:

Front end interview factory handwritten source code series (1)

Two column layout

Two column layout:The left and right columns are fixed on the left and adaptive on the right

design sketch

Front end interview factory handwritten source code series (1)

  1. The first way—float

    HTML part:

    <div class="outer outer1">
        <div class="left">1-left</div>
        <div class="right">1-right</div>
    </div>

    CSS part:

    .outer1 .left {
        width: 200px;
        float: left;
    }
    .outer1 .right {
        width: auto;
        margin-left: 200px;
    }
  2. The second way—flex

    HTML part:

    <div class="outer outer2">
        <div class="left">2-left</div>
        <div class="right">2-right</div>
    </div>

    CSS part:

    .outer2 {
       display: flex;
    }
    .outer2 .left {
       flex: 0 0 200px;
       /* flex-grow: 0;
       flex-shrink:0;
       flex-basis:200px; */
    }
    .outer2 .right {
       flex: auto;
    }
    
    Note: Flex: 0.0200px is the abbreviation of flex: Flex grow flex shrink flex basis
  3. The third way—position

    HTML part:

    <div class="outer outer3">
       <div class="left">3-left</div>
       <div class="right">3-right</div>
    </div>

    CSS part:

    .outer3 {
       position: relative;
    }
    .outer3 .left {
       position: absolute;
       width: 200px;
    }
    .outer3 .right {
       margin-left: 200px;
    }
  4. The fourth way—position again

    HTML part:

    <div class="outer outer4">
        <div class="left">4-left</div>
        <div class="right">4-right</div>
    </div>

    CSS part:

    .outer4 {
        position: relative;
    }
    .outer4 .left {
        width: 200px;
    } 
    .outer4 .right {
        position: absolute;
        top: 0;
        left: 200px;
        right: 0;
    }

Three column layout

Three column layout:Middle column adaptive width, fixed width on both sides

design sketch

Front end interview factory handwritten source code series (1)

  1. The first way—location

    HTML part:

    <div class="outer outer1">
       <div class="left">1-left</div>
       <div class="middle">1-middle</div>
       <div class="right">1-right</div>
    </div>

    CSS part:

    .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;
    }
    Note: use absolute positioning on the left and right respectively, and set the outer margin in the middle
  2. The second way—Flex layout

    HTML part:

    <div class="outer outer2">
       <div class="left">2-left</div>
       <div class="middle">2-middle</div>
       <div class="right">2-right</div>
    </div>

    CSS part:

    .outer2 {
       display: flex;
    }
    .outer2 .left {
       flex: 0 0 100px;
    }
    .outer2 .middle {
       flex: auto;
    }
    .outer2 .right {
       flex: 0 0 200px;
    }
  3. The third way—Floating principle

    HTML part:

    <div class="outer outer3">
       <div class="left">3-left</div>
       <div class="right">3-right</div>
       <div class="middle">3-middle</div>
    </div>

    CSS part:

    .outer3 .left{
       float: left;
       width: 100px;
    }
    .outer3 .right {
       float: right;
       width: 200px;
    }
    .outer3 .middle {
       margin: 0 200px 0 100px;
    }

Grail layout

Grail layout:Middle priority rendering, independent left middle right structure

The specific steps to realize the Grail layout are as follows:

  1. Let the left and right float in a line display, relative positioning
  2. Let the middle width of the middle module be 100%
  3. Move the color block on the left to the front of middle, margin- left:-100%
  4. Let the color block on the right move to the back of middle, margin- left:- width
  5. Add an infilled attribute padding to the parent elements of the three blocks, so as to fill in the middle
  6. Move the left block to the left left:-200px To move the block on the right to the right right:-200px

design sketch

Front end interview factory handwritten source code series (1)

HTML part:

<header>header</header>
   <div class="container">
      <div class="middle">midlle</div>
      <div class="left">left</div>
      <div class="right">right</div>
   </div>
<footer>footer</footer>

CSS part:

header, footer {
   height: 100px;
   width: 100%;
   background-color: antiquewhite;
}
.container {
   height: 200px;
   padding-left: 200px;
   padding-right: 300px;
}
.container > div {
   float: left;
   position: relative;
   height: 100%;
}
.left {
   width: 200px;
   height: 200px;
   background-color: burlywood;
   margin-left: -100%;
   left: -200px;
}
.right {
   width: 300px;
   height: 200px;
   background-color: burlywood;
   margin-left: -300px;
   right: -300px;
}
.middle {
   width: 100%;
   height: 200px;
   background-color: #b0f9c2;
}

Double wing configuration

Double wing configuration

The steps to realize the double wing layout are as follows

  1. Add floats to the left, middle and right, and display them in one line
  2. 100% width for middle
  3. Let the left module move the left margin of middle- left:-100%
  4. Let the module on the right move the right margin of middle- left:- Self width
  5. Add the outer space margin: around the container in the middle

effect:

Front end interview factory handwritten source code series (1)

HTML section

<div class="main">
    <div class="middle">
            < div class = "middle inner" > middle < / div >
    </div>
    < div class = "left" > left < / div >
    < div class = "right" > right < / div > right
</div>

CSS part

.main>div { 
    float:left;
    position: relative;
    height: 300px; 
}
.middle { 
    width: 100%;
    background-color: lightgreen 
}
.left { 
   width:200px;
   margin-left:-100%;
   background-color:#b0f9c2 
}
.right { 
   width: 200px;
   margin-left:-200px;
   background-color:pink 
}
.middle-inner{
   margin:0 200px; 
   background-color: burlywood; 
   height:300px;
}

Horizontal vertical center

HTML section

<div class="box" id="box">
   Shi Xiaoming
</div>

CSS part

Public sector

body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
.box {
    box-sizing: border-box;
    width: 100px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    font-size: 16px;
    border: 1px solid lightblue;
    background: lightcyan;
}

First:location

.box {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -50px;
    margin-top: -25px;
}

be carefulThe above method is to know the specific width and height. But the following way is to know the width and height, but do not use the width and height.

The second type:flex

body {
    display: flex;
    justify-content: center;
    align-items: center;
}

be careful: this way is also not very compatible

The third kind:JavaScript

let html = document.documentElement,
            winW = html.clientWidth,
            winH = html.clientHeight,
            boxW =  box.offsetWidth , // offsetwidth with border
            boxH = box.offsetHeight;

            box.style.position = 'absolute';
            box.style.left = (winW - boxW) / 2 + 'px';
            box.style.top = (winH - boxH) / 2 + 'px';

The fourth kind:table-cell

body {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

summary

The common CSS, JS part of the common handwritten principle problems summarized above. Hope to have small partners need, please think carefully and read, there will be harvest. I hope you get a satisfactory offer~ ❤️

last

Welcome to join us, learn the front end together and make progress together!
Front end interview factory handwritten source code series (1)
Front end interview factory handwritten source code series (1)

Recommended Today

ASP.NET Example of core MVC getting the parameters of the request

preface An HTTP request is a standard IO operation. The request is I, which is the input; the responsive o is the output. Any web development framework is actually doing these two things Accept the request and parse to get the parameters Render according to the parameters and output the response content So let’s learn […]