用来写文档
刚知道的一个库:
Rxjs
如何解决a标点击后hover事件失效的问题?
改变a标签css属性的排列顺序: link→visited→hover→active
各个阶段的含义:
a:link
:未访问时的样式,一般省略成aa:visited
:已经访问后的样式a:hover
:鼠标移上去时的样式a:active
:鼠标按下时的样式
点击一个input依次触发的事件
const text = document.getElementById('text');
text.onclick = function (e) {
console.log('onclick')
}
text.onfocus = function (e) {
console.log('onfocus')
}
text.onmousedown = function (e) {
console.log('onmousedown')
}
text.onmouseenter = function (e) {
console.log('onmouseenter')
}
//先后顺序
'onmouseenter'
'onmousedown'
'onfocus'
'onclick'
docoment,window,html,body的层级关系
window > document > html > body
window
是BOM
的核心对象,它一方面用来获取或设置浏览器的属性和行为,另一方面作为一个全局对象。document
对象是一个跟文档相关的对象,拥有一些操作文档内容的功能。但是地位没有window
高。html
元素对象和document
元素对象是属于html
文档的DOM
对象,可以认为就是html
源代码中那些标签所化成的对象。他们跟div
、select
什么对象没有根本区别。
有写过原生的自定义事件吗
ps:我还是第一次听说这个。
原生自定义事件有三种写法:
1.使用Event
2.使用customEvent
(可以传参数)
3.使用document.createEvent('CustomEvent')
和initCustomEvent()
事件的监听
button.addEventListener('event_name', function (e) {})
事件的触发
dispatchEvent(myEvent)
注意,这里的参数是要自定义事件的对象(也就是
myEvent
),而不是自定义事件的名称('myEvent')
示例
// 1.
// let myEvent = new Event('myEvent');
// 2.
// let myEvent = new CustomEvent('myEvent', {
// detail: {
// name: 'lindaidai'
// }
// })
// 3.
let myEvent = document.createEvent('CustomEvent');
myEvent.initEvent('myEvent', true, true)
let btn = document.getElementsByTagName('button')[0]
btn.addEventListener('myEvent', function (e) {
console.log(e)
console.log(e.detail)
})
setTimeout(() => {
btn.dispatchEvent(myEvent)
}, 2000)
所有的事件都有冒泡吗?
并不是所有的事件都有冒泡的,例如以下事件就没有:
onblur
onfocus
onmouseenter
onmouseleave
手写实现instanceof
//其实就是一层一层的原型链上面找,直到null为止
function myInstanceof (left, right) {
//基本数据类型直接返回false
if(typeof left !== 'object' || left === null) return false;
let proto = Object.getPrototypeOf(left);
while (true) {
if (proto === null) return false;
if (proto === right.prototype) return true;
proto = Object.getPrototypeOf(proto)
}
}
webpack中的loader和plugin有什么区别
ps:webpack一直是我薄弱的地方,虽然看了,但还是不是很理解,可能要手动跟着实现webpack后方能真正领悟吧。
可参考:「吐血整理」再来一打Webpack面试题(持续更新)
loader
它是一个转换器,只专注于转换文件这一个领域,完成压缩、打包、语言编译,它仅仅是为了打包。并且运行在打包之前。
而plugin
是一个扩展器,它丰富了webpack
本身,为其进行一些其它功能的扩展。它不局限于打包,资源的加载,还有其它的功能。所以它是在整个编译周期都起作用。
HTTP和TCP的不同
ps:http
也是我的薄弱之处,这里只是记录了大概的答案,其实我并不理解
HTTP
的责任是去定义数据,在两台计算机相互传递信息时,HTTP
规定了每段数据以什么形式表达才是能够被另外一台计算机理解。
而TCP
所要规定的是数据应该怎么传输才能稳定且高效的传递与计算机之间。
TCP和UDP的区别
1.TCP
是一个面向连接的、可靠的、基于字节流的传输层协议。
2.UDP
是一个面向无连接的传输层协议。
TCP
为什么可靠,是因为它有三次握手来保证双方都有接受和发送数据的能力。
字节流服务:将大块数据分割为以报文段为单位的数据包进行管理
CommonJS和ES6模块的区别
ps: 真的是老火,这几种规范我都不知道看过多少次了,看了忘,理解了下次又不记得。
参考: 一篇不是标题党的CommonJS和ES6模块规范讲解
ps: 看完了,更新一下,感觉现在对这几种方式认识更加清晰了。小小的总结一下:
1.commonjs
主要用于服务端,输出的是值拷贝,但是对象还是共享相同的地址,运行时才加载。
2.为了解决commonjs
同步以及为了客户端,有了amd
和cmd
,它们的区别是amd
先加载模块在执行,而cmd
可以随时自己去加载模块。 (amd
可以用async
去记忆)。
//AMD
define(['m1'], function (m1) {
console.log('我是math, 我被加载了...')
var add = function (a, b) {
return a + b;
}
var print = function () {
console.log(m1.name)
}
return {
add: add,
print: print
}
})
//CMD
define(function (require, exports, module) {
console.log('我是math, 我被加载了...')
var m1 = require('m1');
var add = function (a, b) {
return a + b;
}
var print = function () {
console.log(m1.name)
}
module.exports = {
add: add,
print: print
}
})
3.es6 modules
输出的是值引用,编译的时候就输出了。
正则里的非如何实现的
^
要是放在[]
里的话就表示"除了^后面的内容都能匹配"
,也就是非的意思。
var str = '123456';
console.log(str.replace(/[^1]/g, '帅'));
// l帅帅帅帅帅
反之,如果是不在[]
里的话则表示开头匹配
:
var str = '123456';
console.log(str.replace(/^1/g, '帅'));
// 帅23456
你知道到哪里查看兼容性吗
可以到Can I use
上去查看,官网地址为:caniuse.com/
移动端中css我不知道的那些单位
vmin
和vmax
:vmin
为当前vw
和vh
中较小的一个值;vmax
为较大的一个值。例如视口宽度375px
,视口高度812px
,则100vmin = 375px;100vmax = 812px;
ex
和ch
:ex
以字符"x"的高度为基准;例如1ex
表示和字符"x"
一样长。ch
以数字"0"的宽度为基准;例如2ch
表示和2个数字"0"
一样长。
利用meta标签把http请求换为https
<meta http-equiv ="Content-Security-Policy" content="upgrade-insecure-requests">
移动端动态计算font-size,保证1rem=100px
ps:很久以前面试时别人问题动态font-size是怎么计算出来的,当时的我不求甚解,没有答出来,现在回顾一下,记录一波。
网页的字体 / 100 = 网页的宽度 / 750
=>
网页的字体 * 750 = 100 * 网页的宽度
=>
网页的字体 = 100 * 网页的宽度 / 750
网页的宽度:document.documentElement.getBoundingClientRect().width
还有一些需要去理解的问题
webpack几种hash的实现原理
webpack如果使用了hash命名,那是每次都会重写生成hash吗
webpack中如何处理图片的?
animation部分,都不太懂
http请求可以怎么拦截
混合加密的好处
浏览器如何验证服务器的身份
ETag首部字段说一下
token会不会被伪造?
前后端如何验证一个用户是否下线了
CSP白名单知道吗?
nginx有配置过吗?
反向代理知道吗?
有用过抓包工具吗?
协商缓存说一下
HTTP中的Keep-Alive有了解过吗?
requestAnimationFrame有了解过吗?
如何在前端实现一个图片压缩
不使用框架如何实现组件按需加载以及原理
babel-plugin-import
手写promise
今天看了另外一篇文章,跟着它的代码敲了下,感觉已经看懂了。剩下的就是自己手写出来,并记住它了。
const isFunction = variable => typeof variable === 'function'
const PENDING = 'PENDING'
const FULFILLED = 'FUNFILLED'
const REJECTED = 'REJECTED'
class MyPromise {
constructor (handle){
if(!isFunction(handle)){
throw new Error('MyPromise must accept a function as a parameter')
}
this._status = PENDING
this._value = undefined
this._fulfilledQueues = []
this._rejectedQueues = []
try {
console.log('进入到内部,执行handle');
handle(this._resolve.bind(this), this._reject.bind(this))
} catch (error) {
this._reject(err)
}
}
_resolve (val){
const run = () => {
if(this._status !== PENDING) return;
const runFulfilled = (value) => {
// 新奇的写法,不断shift来达到递归的效果
let cb
while (cb = this._fulfilledQueues.shift()) {
cb(val)
}
}
const runRejected = (err) => {
let cb
while (cb = this._rejectedQueues.shift()) {
cb(err)
}
}
// 如果resolve的是一个promise时,需要再then一下
if(val instanceof MyPromise){
console.log('resolve是promise呀');
val.then(value => {
this._status = FULFILLED
this._value = value
runFulfilled(value)
}, err => {
this._status = REJECTED
this._value = err
runRejected(err)
})
}else{
console.log('resolve啦');
this._status = FULFILLED
this._value = val
runFulfilled(val)
}
}
setTimeout(run, 0)
}
_reject (err){
if(this._status !== PENDING) return;
const run = () => {
this._status = REJECTED
this._value = err
let cb
while (cb = this._rejectedQueues.shift()) {
cb(err)
}
}
setTimeout(run, 0)
}
then (onFulfilled, onRejected){
const {_value, _status} = this
console.log('进入then内部');
// 返回一个promise,保证链式操作
return new MyPromise((onFulfilledNext, onRejectedNext) => {
console.log('进入then promise返回', _status);
let fulfilled = val => {
console.log('变状态了!!!!!!!')
try {
if(!isFunction(onFulfilled)){
onFulfilledNext(val)
}else{
let res = onFulfilled(val)
// 如果then方法的返回值是promise就在then一下
if(res instanceof MyPromise){
res.then(onFulfilledNext, onRejectedNext)
}else{
console.log(`链式操作返回的res: ${res}`)
onFulfilledNext(res)
}
}
} catch (error) {
onRejectedNext(error)
}
}
let rejected = err => {
try {
if(!isFunction(onRejected)){
onFulfilledNext(err)
}else{
let res = onRejected(err)
if(res instanceof MyPromise){
res.then(onFulfilledNext, onRejectedNext)
}else{
onRejectedNext(res)
}
}
} catch (error) {
onFulfilledNext(error)
}
}
switch (_status){
case PENDING:
this._fulfilledQueues.push(fulfilled)
this._rejectedQueues.push(rejected)
break
case FULFILLED:
fulfilled(value)
break
case REJECTED:
rejected(_value)
break
}
})
}
}
let p1 = new MyPromise((resolve, reject) => {
console.log('进入到promise了')
setTimeout(() => {
console.log('准备resolve了')
resolve('FULFILLED')
}, 1000)
})
let p2 = p1.then(res => {
return res + '111111'
})
p2.then((res) => {
console.log(res)
return 1
})