**一. 浏览器运行态下的JS(BOM DOM ECMAScript) **
1. ECMAScript 主要负责基础逻辑 数据处理
2. DOM 浏览器视窗内文本的相应操作
3. BOM 对于浏览器本身区域能力的操作
** 二. BOM**
1. location:
.href: 完整路径,路径栏所有。‘https://www.baidu.com/search?eat=mantou#num’
.origin: 域名部分 ‘https://www.baidu.com’
.protocol: 协议部分 ‘https:’
.post: 不包含协议的域名 ‘www.baidu.com’
.port: 端口号 ‘’
.pathname: 域名后的路径名 ‘/search/’
.search: 参数 不带hash ‘?eat=mantou’
.hash: '#num'
.assign(''): 跳转到指定path 替换pathname的值
.replace(''): 同上,同时会替换浏览地址 导致不能返回,没有上次的历史记录。
.reload(): 刷新
.toString(): 产出当前地址字符串
2. history:
.state: 存储当前页面的状态
.pushState 、replaceState 通过这两种方法来实现 不刷新浏览器跳转路由。对历史记录进行一个存储
3. navigator: 浏览器信息集合
.userAgent: 当前用户的环境信息
可以读取信息 根据不同环境做一些浏览器兼容和上报信息的问题
4. screen: 荧幕
window的视窗判断:
全局入口处获取:
window.innerHeight
window.innerWidth
文本处获取:
document.documentElement.clientHeight
document.documentElement.clientWidth
document.body.clientHeight
document.body.clientWidth
网页视图的size
offsetHeight = clientHeight + 滚动条 + 边框
document.documentElement.offsetHeight
document.documentElement.offsetWidth
document.body.offsetHeight
document.body.offsetWidth
el.getBoundingClientRact()元素上下左右的位置
三. Event事件模型
1. 冒泡: 从内向外 冒泡
2. 捕获: 从外向内 捕获
3. 如何阻止事件的冒泡?
event.stopPropagation()
`
手写兼容性事件绑定
IE - attachEvent vs addEventlistener
区别: attachEvent 事件名要加 ‘on’
a. 执行顺序 attachEvent 后绑定先执行 addEventlistener 先绑定先执行
b. 解绑 detachEvent removeEventlistener
c. 阻断 event.cancelBubble = true vs event.stopPropagetion()
d. 阻止默认事件 event.returnValue = false vs event.preventDefault()
class binEvent {
constructor(element) {
this.element = element
}
// 绑定
addEventListener = (type, handle) => {
if(this.element.addEventlistener) {
this.element.addEventlistener(type, handle)
} else if(this.element.attachEvent) {
this.element.attachEvent('on' + type , () => {
handle.call(element)
})
} else {
this.element['on' + type] = handle
}
}
// 解绑
removeEventListener = (type, handle) => {
if(this.element.removeEventlistener) {
this.element.removeEventlistener(type, handle)
} else if(this.element.detachEvent) {
this.element.detachEvent('on' + type , () => {
handle.call(element)
})
} else {
this.element['on' + type] = null
}
}
// 阻断
static stopPropagation(e) {
if(e.stopPropagation) {
e.stopPropagation()
} else {
et.cancelBubble = true
}
}
// 默认拦截
static preventDefault(e) {
if (e.preventDefault) {
e.preventDefault()
} else {
e.returnValue = false
}
}
}
`
四. 网络层(封装ajax)
`
function ajax (options) {
const { url, methods, data, timeout, async } = options;
const xhr = XHLHttpRequest()
// 配置超时时间
if(timeout) {
xhr.timeout = timeout
}
return new Promise((resolve, reject) => {
// 成功
xhr.onreadystatuschange = () => {
if(xhr.readyState === 4) {
if(xhr.status >= 200 &&
xhr.status < 300 ||
xhr.status === 304) {
resolve(xhr.responsText)
} else {
reject()
}
}
}
// 失败
xhr.onerror = () => reject()
xhr.timeout = () => reject('timeout')
// 传参处理
let params = []
let encoedData = ''
if (data instanceof Object) {
for(let key in data) {
params.push(
encodeURIComponent(key)
+ '=' +
encodeURIComponent(data[key])
)
}
encoedData = params.join('&')
}
// 判断method链接
if(methods === 'get') {
const index = url.indexOf('?')
if(index === -1) {
url += '?'
} else if(index !== url.length-1) {
url += '&'
}
rul += encoedData
}
// 建立链接
xhr.open(methods, url, async)
// 发送请求
if(methods === 'get') {
xhr.send(null)
} else {
xhr.setRequestHeader (
'content-type': 'application/x-www-from-urlencoded'
// 设置传送的内容类型
)
xhr.send(encodeData)
}
})
}
`