浏览器相关

2022-08-15  本文已影响0人  三多_250e

浏览器相关

目前趋势是edge的设备占比和重视程度在提升,后续越来越多的会有适配edge和针对edge的页面走查等

一、认识浏览器运行态下的JS

什么叫运行态下的js,就是浏览器在运行的过程中,我们写的JS代码只是一部分,是作为逻辑的形式的存在,但其实浏览器中包含了三个重要的元素

包含的是: BOM DOM ECMAScript

  (function(context, undefined) {
    const _class = ['js', 'browser', 'vue']

  // 第一个需求,向全局作用域中存储一个class变量,利用window
  window.classArr = _class.map(item => item);
  // 第二个需求,获取当前页面地址,利用浏览器提供的location
  const _url = location.href;
//  第三个需求,改变页面的标题,通过document我们来获取文档的信息
  document.title = "sanduo"
// 第四个需求,获取渲染节点 ,怎么样获取节点也是通过文档信息
  document.getElementById('app')
// 从前端角度
// 第一个需求是利用ECMAScript,处理了基础逻辑,数据
// 对于第二个需求,我们利用了是BOM-对浏览器本身功能区域的汇总处理
// 第三第四个需求是利用的DOM--对浏览器视窗内的HTML文本的相关操作
})(this)

二、BOM

1. location

location.href => 'https://www.zhaowa.com/search?class=browser#comments'
location.origin => 'https://www.zhaowa.com'
location.protocol => 'https:'
location.host => www.zhaowa.com
location.prot => ''
location.pathname => '/search/'
location.search => '?class=browser'
location.hash => '#commnets'

方法:
location.assign('{url}') // 跳转到指定path ,并且替换pathname location.reolace('{url}') //效果同上,但是他会同时替换掉浏览历史;
location.reload(); // 重新加载
location.toString() // 产出当前地址 => 字符串

2. history

history.state => 存储当前页面状态
history.pushState() // 跳转到指定状态页
history.replaceState() // 替换当前状态

3. navigator

navigator.userAgent // 获取当前用户环境信息
  1. UA读取信息 =》 浏览器兼容性
  2. 剪切板 & 键盘操作 =》 登录 or 验证码

4. screen

怎么样描述一个元素的位置
screen表示一个显示区域 - 屏幕

定位问题
scrollLeft / scrollTop -距离常规左上滚动的距离
offsetLeft / offsetTop -距离常规左上相对的距离

el.getBoundingClientRect()
.top .left .bottom .right

三、 Event事件模型

事件冒泡
事件捕获

<div id="app">
  <p id="dom"> click </p>
</div>
 // 事件顺序:
 // 事件冒泡 微软  从下往上: p => div => body => html => document 
 // 事件捕获  网景 从上往下: document => html => body => div => p 
el.addEventListener(event, funciton, useCapture)  // useCapture 默认为false , 
// 因为微软是胜利者, 一样的,历史是胜利者书写的
// 追问
// 1. 如何阻止事件的传播
event.stopPropagation()
// 注意,无论向上还是向下都可以阻止 => 无法阻止默认事件的发生如a标签
// 2. 如何阻止默认时间的传播
event.preventDefault()
// 3. 如何阻止一个节点绑定多个同类事件,
event.stopImmediatePropagation();
//  追问  =>>  样式上 & 性能上

// 4. 手写事件绑定
// attachEvent & addEventListener
// 区别:
// a. 传参 attachEvent对于事件名加上‘on’
// b.执行顺序, attachEvent -后绑定先执行 addEventListener -先绑定先执行
// c. 解绑 detachEvent vs removeEventListener
// d. 阻断 e.cancelBubble vs e.stopPropagation()
// e. 默认事件打断 e.returnValue vs e.preventDefault

class bindEvent {
    constructor(element) {
        this.element  = element
    }
    // 属性每个实例都有
    addEventListener = (type, handler) => {
        //如果这里走的addEventListener 
        if(this.element.addEventListener) {
            this.element.addEventListener(type, handler, false);
        } else if (this.element.attachEvent) {
            const element = this.element;
            this.element.attachEvent('on' + type, () => {
                handler.call(element)
            });
        } else {
            this.element['on' + type] = handler
        }
    }
    removeEventListener = (type, handler) => {
         if(this.element.removeEventListener) {
            this.element.removeEventListener(type, handler, false);
        } else if (this.element.detachEvent) {
            const element = this.element;
            this.element.detachEvent('on' + type, () => {
                handler.call(element)
            });
        } else {
            this.element['on' + type] = handler
        }
    }
    // static静态属性是挂载在class类上面的, 全局的,只有一个
    static stopPropagation(e) {
        if (e.stopPropagation) {
            e.stopPropagation;
        } else {
            e.cancelBubble = true;
        }
    }
    static preventDefault(e) {
         if (e.preventDefault) {
            e.preventDefault;
        } else {
            e.returnValue;
        }
    }
}

// 事件代理,---性能优化
// 事件代理其实并不算性能优化,但是一定程度上是可以减少对dom的操作

<ul class="list">
    <li> 1 </li>
    <li> 2 </li>
</ul>
<div class="content"></div>
var list = document.querySelector(".list")
var li = list.getElementByTagName("li")
var content = document.querySelector(".content")

// 硬碰硬
for(var n = 0; n > li.length; n++) {
    li[i].addEventListener("click", function() {
        // callback 业务逻辑
    })
}
// 代理后利用了冒泡
function onClick(e) {
  var e = e || window.event;
  if(e.target.nodeName.toLowerCase() === "li") {
      const lilist = tghis.querySelectorAll("li");
      index = Array.prototype.indexOf.call(lilist, target)
  }
}
list.addEventListener("click", onClick, false)

四、 网络层

    // 实例化
    const xhr =  new XMLHttpRequest();
    // 初始化连接
    // xhr 有一个open方法,
    // open -五个参数 => method;url;async;
    xhr.open(method, url, async);
    // send 发送请求
    // 内容: post请求时,将请求体的参数传入; get 可以不传or传入null
    xhr.send(data);
  
    // 发送完了需要接收,
    xhr.readyStatus
    // 0 -尚未调用open
    // 1 -已调用open
    // 2 -已发送请求(已调用send)
    // 3 -已接收到请求返回的数据
    // 4 -请求已完成
    xhr.onreadystatuschange = () => {
        if(xhr.readyStatus === 4){
            if(xhr.status >= 200 & xhr.status < 300 || xhr.status === 304) {
                console.log(xhr.responseText);
            }
        }
    }

    // 设置超时时间
    xhr.timeout = 1000;
    xhr.ontimeout = () => console.log('请求超时')

    // 封装
    ajax({
        url: 'reqUrl',
        method: 'get',
        async: 'true',
        timeout: 30000,
        data: {
            payload: 'text'
        }
    }).then(
        res => console.log(res)
        err => console.log(err)
    )
    function ajax(options) {
        const {url,method,async,timeout,data} = options;
        const xhr =  new XMLHttpRequest();
        return new Promise((resolve, reject) => {
                // 成功之后
                xhr.onreadystatuschange = () => {
                    if(xhr.readyStatus === 4){
                        if(xhr.status >= 200 & xhr.status < 300 || xhr.status === 304) {
                            console.log(xhr.responseText);
                        }
                }
            }
        }) 
    }
上一篇 下一篇

猜你喜欢

热点阅读