浏览器详解

我心飞翔 分类:javascript

浏览器内置对象详解

什么是浏览器对象模型

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

  1. window 对象:BOM 的核心,是 js 访问浏览器的接口,也是 ES 规定的 Global 对象
  2. location 对象:提供当前窗口中的加载的文档有关的信息和一些导航功能。既是 window 对象属性,也是 document 的对象属性
  3. navigation 对象:获取浏览器的系统信息
  4. screen 对象:用来表示浏览器窗口外部的显示器的信息等
  5. history 对象:保存用户上网的历史信息

Window 对象

windows 对象是整个浏览器对象模型的核心,其扮演着既是接口又是全局对象的角色

window 对象的属性和方法

属性 说明
alert() 系统警告对话框,接收字符串参数并显示
confirm() 系统确认对话框,可提供确认或取消两种事件
prompt() 提示对话框,可对用户展示确认、取消事件外,还可提供文本域
open(url,[target,string,boolean]) 可导航至特定的 url,又可打开一个新的浏览器窗口
url: 要加载的URL
target: 窗口目标
string: 特定的字符串,以逗号分隔的字符串表示新窗口显示的特性
boolean: 表示新页面是否取代浏览器历史记录中当前加载页面的布尔值
onerror() 事件处理程序,当未捕获的异常传播到调用栈上时就会调用它,并把错误消息输出到浏览器的 JavaScript 控制上
window.onerror(描述错误的一条消息, 字符串--存放引发错误的JavaScript代码所在的文档url, 文档中发生错误的行数)
setTimeout() 超时调用——在指定的时间过后执行代码
window.setTimeout(function(){...},毫秒)
setInterval() 间歇调用——每隔指定的时间就执行一次
window.setInterval(function(){...},毫秒)

窗口位置的属性与方法

属性 说明 兼容性
screenLeft 窗口相对于屏幕左边的位置 适用于IE、Safari、Chrome
screenTop 窗口相对于屏幕上边的位置 适用于IE、Safari、Chrome
screenX 窗口相对于屏幕左边的位置 适用于Firefox
screenY 窗口相对于屏幕上边的位置 适用于Firefox
moveBy(x,y) 接收的是在水平和垂直方向上移动的像素数 全兼容
moveTo(x,y) 接收的是新位置的x和y坐标值 全兼容
// 跨浏览器获取窗口左边和上边位置
let leftPos = (typeof window.screenLeft == 'number') ? window.screenLeft : window.screenX
let topPos = (typeof window.screenTop == 'number') ? window.screenTop : window.screenY  
 

窗口大小的属性与方法

属性 说明
innerWidth
innerHeight
IE9+、Safari、Firefox、Opera: 该容器中页面视图区的大小
Chrome: 返回视口大小
移动设备: 返回可见视口(即屏幕上可见页面区域的大小)
移动IE浏览器: 不支持该属性,当移动IE浏览器将布局视口的信息保存至document.body.clientWidthdocument.body.clientHeight
outerWidth
outerHeight
IE9+、Safari、Firefox: 返回浏览器窗口本身的尺寸
Opera: 返回页面视图容器的大小
Chrome: 返回视口大小
resizeTo(width, height) 接收浏览器窗口的新宽度与新高度
resizeBy(width, height) 接收新窗口与原窗口的宽度与高度之差

Location 对象

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

window.location === document.location //true
 

主要属性及方法

属性 例子 说明
hash #host 返回 url 中的 hash(#后字符>=0)
host juejin.im:80 服务器名称+端口(如果有)
hostname juejin.im 只含服务器名称
href https://zine-fj.github.io/blog/ 当前加载页面的完整的 url
pathname /blog 返回 url 的的目录和(或)文件名
port 8080 url 的端口号,如果不存在则返回空
protocol https: (or http:) 页面使用的协议
search ?name=aha&age=20 返回 url 的查询字符串,以问号开头

Navigation 对象

表示用户代理的状态和标识,允许脚本查询它和注册自己进行一些活动
浏览器中 navigation --> navigator

主要属性

属性 说明
onLine 表示浏览器是否连接到了因特网
... ...

Screen 对象

提供有关窗口显示的大小和可用的颜色输入信息。

主要属性及方法

属性 说明
width 屏幕的像素宽度
height 屏幕的像素高度
... ...

History 对象

history 对象保存着用户上网的历史记录,从窗口被打开的那一刻算起,history 对象是用窗口的浏览历史用文档和文档状态列表的形式表示。history 对象的 length 属性表示浏览历史列表中的元素数量,但出于安全考虑,脚本不能访问已保存的 url

主要属性及方法

属性 说明
go() 1. 以在用户的历史记录中任意跳转,go(n)表示前进 n 页,go(-n)表示后退 n 页(n>0)
2、go()可以传递字符串参数,浏览器历史中如果有这条 url 则实现跳转至包含该字符串的第一个位置,否则什么也不做
back() 后退一页
forword() 前进一页
length 保存历史记录的数量,可用于检测当前页面是否是用户历史记录的第一页
history.length === 0

浏览器事件模型详解

浏览器的事件捕获,冒泡

浏览器事件模型中的过程主要分为三个阶段:捕获阶段、目标阶段、冒泡阶段。
事件模型.jpg

第三个参数

addEventListener 的第三个参数

// true 代表在捕获阶段
// false 代表在冒泡阶段
oDiv.addEventListener('click',function(e){},true)
 
<div>
    父级 father
    <span> 子级 son </span>
</div>
// e.target 当前点击的元素
// e.currentTarget 绑定监听事件的元素
father.addEventListener('click',function(e) {
    console.log('parent 捕获',e.target.nodeName,e.currentTarget.nodeName); // span DIV
},true);

span.addEventListener('click',function(e) {
    console.log('son 冒泡',e.targetnodeName,e.currentTarget.nodeName); // span SPAN
},false);
 

addEventListener 多浏览器兼容的绑定函数封装方法:

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

阻止事件传播 和 阻止默认行为

e.stopPropagation():阻止冒泡,阻止捕获阶段传播
e.preventDefault():阻止默认事件发生,如点击a链接跳转
兼容性封装(针对IE):

function stopPropagation(ev) {
    if(ev.stopPropagation) {
        ev.stopPropagation();
    } else {
        ev.cancelBubble = true; // IE里不支持事件捕获,这里是取消冒泡。
    }
}
function preventDefault(ev) {
    if(ev.preventDefault) {
        ev.preventDefault();
    } else {
        ev.returenValue = false; // IE
    }
}
 

案例:用事件委托方法实现 ul+li,点击 li 打印对应索引

<ul id="ul">
    <li>1</li>
    <li>2</li>
</ul>

<script>
    // 事件委托
    let ul = document.getElementById('ul');
    ul.addEventListener('click',function(e) {
        let target = e.target;
        if(target.tagName.toLowerCase() == 'li') {
            const liList = this.querySelectorAll('li');
            const index = Array.prototype.indexOf.call(liList,target); // liLIst.indexOf(target)
            // console.log(Array.from(liList));
            console.log(`内容:${target.innerHTML},索引:${index}`);
        }
    })
</script>
 

浏览器请求相关内容详解

请求方式

fetch

fetch(url,{method: 'GET'})
.then(res => res.json())
.then(json => console.log(json))
.then(error => console.log('error:',error))
 

默认四种缺点:

  1. 不带 cookie
  2. 错误不会 reject
  3. 不支持超时设置
  4. 需要借用 AbortController 中止 fetch

在代码中如何解决:

// 1. 默认不带 cookie
fetch(url,{
    method: 'GET',
    credentials: 'same-origin' // 设置带 cookie
})
 
// 2. 错误不会reject(.catch 不会被触发)
// http 错误,比如404 5xx,不会导致fetch返回的promise标记为reject
// 想要精确判断fetch是否成功,需要包含promise resove 的情况,判断 response.ok 是不是为 true;
fetch(url,{
    method: 'GET',
})
.then((response)=>{
    if(response.ok) {
        return response.json();
    } else {
        return new Error('fetch error');
    }
})
.then(json=>console.log(json))
.catch(error=>console.error(error))
 
// 3. 不支持设置超时
function fetchTimeout(url,init,timeout = 9999) {
    return new Promise((resolve,reejct)=>{
        // 1、不超时情况,fetch resolve/reject
        // 2、10s 超时情况
        fetch(url,init)
            .then(resolve)
            .catch(reject);
        setTimeout(reject,timeout)
    })
}
 
// 4. 可以中止 fetch (xhr 不可中止,除非关页面)
const controller = new AbortController();

fetch('https://demain/service',{
    method: 'GET',
    signal: controller.signal
})
// .then(...)

// 想要中止时
controller.abort();
 

ajax

简单的 ajax 请求代码:

let xhr = new XMLHttpRequest();
xhr.open('GET', url);

// 监听事件
xhr.onreadystatechange = function () {
    // request completed?
    if (xhr.readyState !== 4) return;

    if (xhr.status === 200) {
        // request successful - show response
        console.log(xhr.responseText);
    } else {
        // request error
        console.log('HTTP error', xhr.status, xhr.statusText);
    }
};

// xhr.timeout = 3000; // 3 seconds
// xhr.ontimeout = () => console.log('timeout', xhr.responseURL);

// progress事件可以报告长时间运行的文件上传
// xhr.upload.onprogress = p => {
//     console.log(Math.round((p.loaded / p.total) * 100) + '%');
// }

// start request
xhr.send();
 

常见返回状态

  • 200 get 成功
  • 201 post 成功
  • 301 永久重定向
  • 302 临时重定向
  • 304 协商缓存 服务器文件未修改
  • 400 客户端请求有语法错误,不能被服务器识别
  • 403 服务器受到请求,但是拒绝提供服务,可能是跨域
  • 404 请求的资源不存在
  • 405 请求的method不允许
  • 500 服务器发生不可预期的错误

参考链接:
浏览器对象模型

回复

我来回复
  • 暂无回复内容