浏览器体系

160 阅读3分钟

前言

话可以收回,但是人生是不可能这样的, 这是我参与「掘金日新计划 · 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
   
   

总结

还需需要详细去学习一下。