浏览器详解

173 阅读3分钟

BOM

BOM(浏览器对象模型),浏览器模型提供了独立于内容、可以与浏览器窗口进行滑动的对象结构,就是浏览器提供的API

五大对象

window对象 是整个浏览器对象模型到核心,是js访问浏览器的接口,也是ES规定的global对象

alert()
prompt()
confirm()
open()
onerror()
--定时器
setTimeout()
setInterval() 不能做倒计时等轮询有非必须bug
--窗口位置
screenLeft
screenTop
screenX
screenY
moveBy(x,y)
moveTo(x,y)
--窗口大小
innerWidth
innerHeight
outerWidth
outerHeight
resizeTo(width, height)
resizeBy(width, height)
window.innerWith || document.body.clientWidth
window.innerHeight || document.body.clientHeight

location对象提供当前窗口中的加载的文档有关的信息和一些导航功能。既是window对象属性,也是document对象属性。

    location.href 返回,可以返回到上一个页面
    location.replace 无法返回到上一个页面
    hash
    host
    hostname
    href
    pathname
    port
    protocol
    search

navigator对象获取浏览器的系统信息

   window.navigator.onLine 是否断网

screen对象用来表示浏览器窗口外部的显示器等信息等。 history对象保存用户上网等历史信息

   history路由和hash路由
   go()
   back()
   forword()
   length

浏览器事件模型

window->document->body->div 捕获过程
window<-document<-body<-div 冒泡过程
window.addEventListener('click', ()=>{
    e.target.nodeName;// 指当前点击元素
    e.currentTarget.nodeName; // 指监听到的元素
}, false)// 默认冒泡阶段, 若true则捕获阶段 
e.canceBulle = true; // ie阻止事件冒泡, ie不支持捕获
e.stopPropagation(); // 阻止事件传播
e.preventDefault(); // 阻止默认行为
e.returnValue = false; // ie

- stopImmediatePropagation() 
如果有多个相同类型事件的事件监听函数绑定到同一个元素,
当该类型的事件触发时,
它们会按照被添加的顺序执行。
如果其中某个监听函数执行了 event.stopImmediatePropagation() 方法,
则当前元素剩下的监听函数将不会被执行。

兼容性

attachEvent——兼容:IE7、IE8; 不支持第三个参数来控制在哪个阶段发生,默认是绑定在冒泡阶段 addEventListener——兼容:firefox、chrome、IE、safari、opera;

class BomEvent{
    constructor(element){
        this.element = element;
    }
    addEvent(type, fn){
        if(this.element.addEventListener){
            this.element.addEventListener(type, fn, false);
        } else if(this.element.attachEvent){
            this.element.attachEvent('on'+type, function(){
                fn.call(element);
            })
        } else {
            this.element['on'+type] =fn;
        }
    }
    
    removeEvent(type, fn){
        if(this.element.removeEventListener){
            this.element.removeEventListener(type, fn, false);
        } else if(this.element.detachEvent){
            this.element.detachEvent('on'+type, function(){
                this.element.detachEvent('on'+type, fn);
            })
        } else {
            this.element['on'+type] =fn;
        }
    }
}

function stopPropagation(ev){
    if(ev.stopProgation){
        ev.stopProgation();
    } else {
        ev.cancelBubble = true;
    }
}

function preventDefault(event){
    if(event.preventDefault){
        event.preventDefault()
    } else{
        event.returnValue = false;
    }
}

浏览器请求相关 ajax、fetch API

1、XMLHTTPRequest
2、fetch
    -  默认不带cookie
    -  错误不会reject
    -  不支持超时设置
    -  需要借用AbortController中止fetch
 3、返回状态码
     200 get 成功
     201 post 成功
     301 永久重定向
     302 临时重定向
     304 协商缓存 服务器文件未修改
     400 客户端请求有语法, 不能被服务器识别
     403 服务器收到请求,但拒绝提供服务,可能是跨域
     404 请求资源不存在
     405 请求的method不允许
     500 服务器发生不可预期的错误
let xhr = new XMLHttpRequest();
xhr.open('get', 'http://domain/service');
xhr.onreadystatechange = function(){
    if(xhr.readyState !== 4) return;
    if(xhr.status === 200){
        console.log(xhr.responseText);
    } else {
        console.log('HTTP error', xhr.staus, xhr.statusText);
    }
}

//xhr.timeout = 3000; //超时3秒
//xhr.ontimeout = ()=> console.log('timeout', xhr.responseURL);
// progress事件可以报告长时间运行的文件上传
//xhr.upload.onpress = p =>{
    console.log(Math.round(p.load/p.total)*100+'%')
}
xhr.send();



fetch(
        'http://domain/service', {
            method: 'GET'
        }
    )
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.error('error:', error));

// 默认不带cookie

fetch(
    'http://domain/service', {
        method: 'GET',
        credentials: 'same-origin'
    }
)

// 错误不会reject
// HTTP错误(例如404 Page Not Found 或 500 Internal Server Error)不会导致Fetch返回的Promise标记为reject;.catch()也不会被执行。
// 想要精确的判断 fetch是否成功,需要包含 promise resolved 的情况,此时再判断 response.ok是不是为 true

fetch(
        'http://domain/service', {
            method: 'GET'
        }
    )
    .then(response => {
        if (response.ok) {
            return response.json();
        }
        throw new Error('Network response was not ok.');
    })
    .then(json => console.log(json))
    .catch(error => console.error('error:', error));

// 不支持直接设置超时, 可以用promise
function fetchTimeout(url, init, timeout = 3000) {
    return new Promise((resolve, reject) => {
        fetch(url, init)
            .then(resolve)
            .catch(reject);
        setTimeout(reject, timeout);
    })
}

// 中止fetch
const controller = new AbortController();

fetch(
        'http://domain/service', {
            method: 'GET',
            signal: controller.signal
        })
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.error('Error:', error));

controller.abort();