三----浏览器相关

一、浏览器主要术语解释

w3c是web规范,浏览器要遵循的网页标准(包括超文本标记语言,html5规范,事件规范等。),ecmascript6、7、8是js运行的标准。
dom是网页文档对象模型,定义了网页文档的操作的api,bom是浏览器对象模型,定义了浏览器操作的apif,它的主要对象是windows,document是windows下的属性。
chrome是v8引擎,safiri是jscore,firefox是spidermonkey
1、encodeURI
会将元字符和语义字符之外的全转码,比如:
http://www.example.com/q=春节
http://www.example.com/q=%e6%98%78%y3
2、encodeURIComponent
http://www.example.com/q=春节
http%3a%2f%2fwww.example.com%2fq=%e6%98%78%y3
在链接跳转的时候用转义比较好。
3、dpi ----设备像素比==物理像素/逻辑像素
分辨率越大,像素点越多,即物理像素比较大,dpi越大。1px所占用的像素越少,dpi越小。

二、浏览器事件

1、浏览器事件模型分为三步,分别是捕获阶段、目标阶段,冒泡阶段,它们之间的关系是:捕获–>目标–>冒泡。
Window.addEventListener(‘click’,function(){},true)//这是捕获阶段进行触发
Window.addEventListener(‘click’,function(){},false)//这是冒泡阶段进行触发
例如:一个结构html–>body–>div–>span;这时点击了div区域,事件触发阶段为html的捕获阶段点击事件–>body的捕获阶段点击事件–>div的捕获阶段的点击事件–>div的冒泡阶段的点击事件–>body的冒泡阶段的点击事件–>window的冒泡阶段的点击事件。
2、阻止事件传播–>e.stopPropagation()。
不仅能阻止冒泡也能阻止捕获传播,如果在某个监听事件中方法中使用了e.stoppropagation,那么当前这个方法的后续还是会执行下去,只是事件的传播停止了。
3、阻止默认事件–>e.preventDefault();
比如a标签的点击事件会带默认的跳转事件,那么在a标签的点击事件中加上e.preventDefault()就不会跳转了。
4、监听同一事件,阻止其他的同一事件执行–>e.stopImmediatePropagation
5、事件委托
事件委托是基于事件冒泡这个过程触发的,例如一个ul列表,里面有很多li,我们需要把每个li点击事件都要获取。那么最简单直接的方式在每个li上进行绑定监听click事件,当有很多的li那么监听器也会越来越多,性能上会有影响。由于有事件冒泡的这个特性,可以将监听器统一绑定在父元素ul上,这样就只有一个监听器了,例如:

<ul id='qqq'>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
let ul = document.getElementById('qqq');
ul.addEventListener('click',function(e){
	//e.target是当前点击的元素对象
	//e.currentTarget是当前绑定监听的元素对象
	if(e.target.tagName.toLowerCase()=='li'){
	let liList = document.querySelectorAll('li')//伪数组
	let realList = Array.from(liList);
	let index = realList.indexOf(e.target)//当前点击元素的索引,对象都有了,就可以根据它处理对应的事了
	//另一种伪数组调用indexof的方法
	let index = Array.prototype.indexOf.call(liList,e.target)
	}
})

6、事件监听不同浏览器不同的监听方法,ie浏览器使用的是attachEvent且默认是绑定在冒泡阶段,以下是实现一个类来兼容不同浏览器的监听方法

class addEventClass {
  constructor(element) {
    this.element = element;
  }
  addEvent(event,handler) {
    if(this.element.addEventListener) {
      this.element.addEventListener(event, handler, false);
    } else if(this.element.attachEvent) {
      this.element.attachEvent('on'+event,handler);
    } else {
      this.element['on'+event] = handler;
    }
  }
  removeEvent(event,handler) {
    if(this.element.removeEventListener) {
      this.element.removeEventListener(event, handler, false);
    } else if(this.element.detachEvent) {
      this.element.detachEvent('on'+event,handler);
    } else {
      this.element['on'+event] = null;
    }
  }
}
function stopPropagation(ev) {
  if(ev.stopPropagation){
    ev.stopPropagation();
  } else {
    ev.cancelBubble = true;
  }
}
function preventDefault(ev) {
  if(ev.preventDefault){
    ev.preventDefault();
  } else {
    ev.returnValue = false;
  }
}

浏览器常用属性及事件:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
一个网络联网的功能:

window.addEventListener('load',function(){
  var status = document.getElementById('status');
  var log = document.getElementById('log');
  function updateOnlineStatus(event) {
    status.innerHTML = navigator.onLine?'online':'offline';
    log.insertAdjacentHTML('beforeend',`event${event.type}`)
  }
  window.addEventListener('online',updateOnlineStatus);
  window.addEventListener('offline',updateOnlineStatus);
})
var {connection} = navigator;
var type = connection.effectiveType;
function updateConnectionStatus(){
  console.log(`网络从${type}切换至${connection.effectiveType}`);
  type = connection.effectiveType;
}
connection.addEventListener('change',updateConnectionStatus)

三、浏览器请求

1、响应码:
200:get请求成功
201:post请求成功
301:永久重定向
302:暂时重定向
304:协商缓存,服务器文件未修改
400:请求参数错误,不被服务端识别
401:身份未认证
403:服务器收到请求,但拒绝提供服务,可能跨域
404:资源未找到
405:请求方式有误
500:服务器内部错误
503:服务器当前无法处理,临时状态
504:网关错误
2、为什么常见的cdn域名和业务域名不一致?

  1. 安全性,浏览器有一个同源策略,不同域名不会携带cookies
  2. 提高带宽利用率,上cdn的资源比如图片等就为了快速拉取,携带cookie浪费带宽资源
  3. 避免产生最大并发请求数,因为浏览器规定同源同域名请求数同一时间请求有限制。

3、针对单页面index.html要求用缓存是协商缓存好还是强缓存?
html里的script和css后面都有hash值,只要重新发布,hash就会变换。
如果index.html使用强缓存,那么在强缓存期间想要重新发布就无法更新有很大的问题。当使用协商缓存,当重新打包时,script和css的hash值变化,index.html检查到自己内容的改变就发起重新请求。
一般请求index.html不做缓存,no-cache,no-store,因为html文件比较小。
4、浏览器ajax和fetch简单实现
ajax:

let xml = new XMLHttpRequest();
xml.open('GET','http://xxx.com');
xml.onreadystatechange = function() {
  if(xml.readyState == 4) {
    //readyState有5种状态
    //0:请求初始化
    //1:服务器已经建立链接
    //2:请求已经接收----发送数据阶段
    //3:请求处理中----接收数据状态
    //4:请求完成
    if(xml.status == 200) {
      console.log(xml.responseText);
    }
  }
}
xml.send();
xml.timeout = 1000;
xml.ontimeout = function() {

}
xml.upload.onprogress = p => {
  console.log(p.loaded/p.total);
}

fetch:
特点:
1、不携带cookie
2、500的错误不会reject
3、不支持超时设置
4、

//不携带cookie
fetch('http://xxx.com',{
  method:'GET',
}).then(response => response.json()
).then(json => console.log(json)
).catch(error => console.log(error))
//同域携带cookie
fetch('http://xxx.com',{
  method:'GET',
  credentials:'same-origin',
}).then(response => response.json()
).then(json => console.log(json)
).catch(error => console.error(error))
//fetch返回的错误不会直接进入catch,需要通过response.ok来判断手动触发catch
fetch('http://xx.com',{
  method:'GET'
}).then(response => {
  if(response.ok) {
    return response.json();
  }
  throw new Error('fetch return is not ok')
  
}).then(json => console.log(json)
).catch(error => console.error(error));

//不支持直接设置超时,可以如此做
function timeOut(url, init, time) {
  return new Promise((resolve,reject) => {
    fetch(url, init).then(resolve).catch(reject);
    setTimeout(() => reject, time);
  })
}

//用AbortController来中止fetch
let controller = new AbortController();
fetch('http://xxx.com',{
  method:'GET',
  siganl:controller.siganl,
})
controller.abort();

四、ajax兼容使用ts实现

interface Option {
  url:string,
  method?:'GET'|'POST',
  data:any,
  timeout:number,
}
function transferData(data: any) {
  let returnList = [];
  for(let key in data) {
  //这里去encode是因为怕data里有url的字符会影响真的url
    returnList.push(`${key}=${encodeURIComponent(data[key])}`);
  }
  return returnList.join('&');
}
export function ajaxTs(options: Option) {
  return new Promise((resolve, reject) => {
    if(!options.url) {
      return;
    }
    let xhr;
    if((window as any).XMLHttpRequest) {
      xhr = new XMLHttpRequest();
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    let queryData = transferData(options.data);
    let timer = null;
    const handleStatus = () => {
      xhr.onreadystatechange = function() {
        if(xhr.readyState == 4) {
          clearTimeout(timer);
          if(xhr.status >=200 && xhr.status < 300 || xhr.status == 304) {
            resolve(xhr.responseText);
          } else {
            reject(xhr.status);
          }
        }
      }
    }
    if(options.method.toUpperCase()=='GET') {
      xhr.open('GET',options.url+'?'+queryData);
      handleStatus();
      xhr.send();
    } else if(options.method.toUpperCase() == 'POST') {
      xhr.open('POST',options.url);
      xhr.setRequestHeader('contentType','application/x-www-form-urlencoded')
      handleStatus();
      xhr.send(options.data);
    }
    if(options.timeout){
      timer = setTimeout(() => xhr.abort(), options.timeout);
    }
  })
}

五、webcomponents
webcomponents是浏览器原生的创建可重用的自定义元素,实现自定义标签,对于夸框架复用有帮助。
它主要实现方式有

  • customElements
  • template----可重用的一套模版,包括html.style等
  • shadow dom 用于隔离自定义元素和样式。
    前两个实现方式都可以用于slot显示。三种方式哦都必须继承HTMLElement。
    常见的webcomponents库有polymer、x-tag、stonel等等。
    例如:
  class TextIcon extends HTMLElement {
    constructor() {
      super()
      this._text = null;
    }
    static observedAttributes = ['text'];
    attributeChangedCallback(name, oldValue, newValue) {
      this._text = newValue;
      this.updateRender();
    }
    connectedCallback() {
      this.updateRender();
    }
    get text () {
      return this._text;
    }
    set text(v) {
      console.log(v, 'ss')
      this.setAttribute('text', v)
    }
    updateRender () {
      this.innerText=this._text
    }
  }
  customElements.define('text-icon', TextIcon)

使用

 <text-icon text="test1"></text-icon>

  const textIcon = document.createElement('text-icon')
  textIcon.setAttribute('text', 'sddd')
  document.body.appendChild(textIcon)

  const textIcon1 = new TextIcon()
  textIcon1.text = 12
  document.body.appendChild(textIcon1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值