前言
话可以收回,但是人生是不可能这样的, 这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
一.认识在浏览器运行态下的JS
包含:BOM.DOM.ECMAScript
(function (context,undefined){
const _class=['js','browser','vue']
//向全局中挂载
window.classArr=_class.map(item=>item)
//获取当前页面的地址
const _url=location.href
//设置Tab标题
document.title="class"
//获取渲染节点
document.getElementById('app')
})
// 追问:了解浏览器JS的执行态
// 简述:
// ECMAScript - 基础逻辑、数据处理
// DOM - 对于浏览器视窗内,文本的相应操作
// BOM - 对于浏览器本身区域能力的处理
二.BOM
1.location
location.href=>'www.dudu.com/search?clas…' =>路径栏所有
.orgin=>'https://www.dudu.com'
.protocol=>'https:'
.host=>'www.dudu.com'
.port=>''
.pathname=>'/search/'
.search=>'?class=browser&id=2'
.assign('')//跳转到指定path=>替换pathname
.replace('')//同上,同时替换浏览历史
.reload()
.toString()//产出当前地址字符串
* 面试方向:
1. location本身api操作 - 提取相关信息、api间对比 => assign vs replace
2. 路由相关: 跳转、参数、操作 => 场景:可返回(history)、是否刷新(hash)=> replace替换assign、携带参数
3. url处理 - 正则 or 手写js处理
4. URI & URL: uniform resource identifier / locator
2.history
history.state=>存储当前页面的状态
history.pushState()
.replaceState()
* 面试方向 - 路由方向 history和hash的模式利弊
3.navigator
*浏览器系统信息大集合
navigator.userAgent // 获取当前用户的环境信息
* 面试方向
1. userAgent 读取信息 => 浏览器兼容性、上报信息
2. 剪切板、键盘
4.screen
面试方向-判断区域大小
window 视窗判断
全局入口处:
window.innerHeigt
window.innerHeigt
文本获取:
document.documentElement.clientHeight
document.documentElement.clientWidth
document.body.clientWidth
document.body.clientHeight
网页视图的SIZE ->offsetHeight=clientHeight+滚动条+边框
document.documentElement.offsetHeight
document.documentElement.offsetWidth
document.body.offsetWidth
document.body.offsetHeight
动态定位
scrollLeft/scrollTop-距离常规左/上滚动距离
offsetLeft/offsetTop-距离常规左/上距离
el.getBoundingClientRect().top
el.getBoundingClientRect().left
el.getBoundingClientRect().bottom
el.getBoundingClientRect().right
三.Event 事件类型
<div id="app">
<p id="dom"></p>
</div>
//冒泡:p->div->body->HTML->document
//捕获;document->HTML->BODY->DIV->P
el.addEventListener(event,function,useCapture)//默认false
//如何阻止事件传播
event.stopPropgation()
//阻止默认事件-a
event.preventDefault()
//相同节点绑定多个同类事件
event.stopImmediatePropagation()
//手写兼容性事件绑定
//IE -attachEvent VS addeEventListener
//区别
//a.传参 attacjEvent 对于事件名需要加上'ON'
//b.z执行顺序:attachEvent -后绑定先执行:addEventListener-先绑定执行
//c.解绑:detachEvent vs removeEVENTListener
/d.阻断:event.cancelkBubble=true vs event.stopPropgation()
//e.默认事件拦截:event.returnValue=false vs event.preventDefault()
class bindEven{
constructor(element){
this.element=element:
}
//绑定
addEventListener=(type,handler)=>{
if(this.element.addEventListener){
this.element.addEventListener(type,handler,false)
}else if(this.element.attachEvent){
this.element.attachEvent('on'+type,()=>{
handler.call(element)
})
}else{
this.element['on'+type]=handler;
}
}
//解绑
removerEventListener=(type,hanler)=>{
if(this.element.removeEventListener){
this.element.removeEventListener(type,handler,false)
}else if(this.element,detachEvent){
this.element.detachEvent('on'+type,()=>{
handler.call(element)
})
}else {
this.element['on'+type]=null
}
}
//阻断
static stopProgation(e){
if(e.stopPropagation){
e.stopPropagation()
}else{e.cancelBubble=true;}
}
//默认拦截
static preventDefault(e){
if(e.preventDefault){
e.preventDefault()
}else{e.returnValue=false}
}
}
//代理后-利用事件传递
function onClick(e){
var e=e || window.event;
if(e.target.nodeName.toLowCase()=='li'){
//业务逻辑
var liList=this.querySelectorAll("li")
}
}
list.addEventListener('click',onClick,false)
四.网络层
//实例
const xhr=new XMLHttpRequest();
//初始化建立
xhr.open(method,url,async)//get post 请求的地址;是否为异步请求
//方法的发送请求-send
xhr.send(data)//get 可以不传或传入null,post endcoeURICompinent 编码拼接
//接收
//xhr.resdyState-0 尚未建立OPEN 1已经调用open 已经调用send 已经收到请求返回 请求已经完成
xhr.onreadyStatuschange=()=>{
if(xhr.readyStatus===4){
if(xhr.status>=200 && xhr.status<300&& xhr.status==304){
//xhr.responseText
}
}
}
//超时时间
xhr.timeout =30000
xhr.ontimeout=()=>{
//超时后
}
//封装手写
ajax({
url:"reqURL",
method:'get',
async:true,
timeout:30000,
data:{
payload:'text'
}
}).then(
res=>{}
err=>{}
).catch(err=>{})
//实现
function ajax(options){
const{
url,
method,
async,
data,
timeout
}=options;
const xhr=new XMLHttpRequest()
//配置超时事件
if(timeout){
xhr.timeout=timeout;
}
return new Promise((resolve,reject)=>{
//c成功
xhr.onreadystatuschange=()=>{
if(xhr.readyStatus==4){
//判断HTTP状态码
if(xhr.status.=200 && xhr.status<300 &&xhr.status==304){
//返回拦截器
resolve(xhr.responseText)
}else{
reject()
}
}
}
//失败
xhr.onerror=err=>reject(err);
xhr.ontimeout=()=>reject('timeout')
//传参处理
let _params=[]
let encodeData=''
if(data instanceof object){
for (key in data){
_params.push(endcodeURICompinent(key)+'='+encondeURIComponent(data[key]))
}
encodeData= _params.join('&')
}
//method判断连续
if(method==='get'){
const index=url.indexOf('?')
if(index==-1){
url+="?"
}else if(index !==url.length-1){
url+='&'
}
url+=encodeData
}
//建立连接
xhr.open(method,url,async)
//请求拦截器
.//发送请求
if(method=='get){
xhr.send(null)
}else{
xhr.setRequestHeader('content-type:'application/x-www-form-urlencoded)
xhr.send(encodeData)
}
})
}
五.浏览器原理
从url输入到页面展示发生了什么 获取资源=>渲染出页面
//dom
//cssom-css解析成树形状数据结构
//Render Tree:dom+cssom生成树
//layout module:计算Render Tree 每个节点具体的状态和位置
//painting:呈现到屏幕上
//流程
//URL =>HTML解析-js +dom+cssom=>render tree/js+css执行=》layout=>painting
//纵向切分
//bytes(62,48,65,2c....)=>characters(<html/>)=>Tokens(tag tree)=>Nodes(html|head|body)=>dom|cssom
总结
还需需要详细去学习一下。