问卷调查网站建设,临清建设网站,表白网页在线生成制作源码,WordPress授权站资源网文章目录浏览器对象详解一、参考资料二、认识浏览器运行态下的 js1.问#xff1a;是否了解浏览器的执行态#xff08;分层设计#xff09;#xff1f;2.BOM1.[location](https://developer.mozilla.org/zh-CN/docs/Web/API/Location)拓展方向#xff1a;2.[History](https…
文章目录浏览器对象详解一、参考资料二、认识浏览器运行态下的 js1.问是否了解浏览器的执行态分层设计2.BOM1.[location](https://developer.mozilla.org/zh-CN/docs/Web/API/Location)拓展方向2.[History](https://developer.mozilla.org/zh-CN/docs/Web/API/History)3.[navigator](https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator)4.[screen](https://developer.mozilla.org/zh-CN/docs/Web/API/Screen)三、浏览器事件1.addEventListener 第三个参数2.阻断事件传播3.阻止默认行为拓展方向性能方向兼容性方向四、网络请求1.XMLHttpRequest2.fetch3.Http 状态码和 Header1.状态码[1|2|3]xx4xx5xx2.字段4.拓展方向如何应对网络不稳定波动的情况如何处理并发请求往期精彩文章浏览器对象详解
一、参考资料
浏览器对象模型聊聊 H5 的 pushState 与 replaceState用 Javascript 获取页面元素的位置js 获取操作元素位置
二、认识浏览器运行态下的 js
1.问是否了解浏览器的执行态分层设计
ECMAScript - 基础逻辑、数据处理js 语法块BOM - 浏览器本身的能力操作 Browser Object Model浏览器对象模型浏览器模型提供了独立于内容的、可以与浏览器窗口进行滑动的对象结构就是浏览器提供的 API DOM - 浏览器文本的操作
2.BOM
1.location 提供当前窗口中的加载的文档有关的信息和一些导航功能。 既是 window 对象属性也是 document 的对象属性 window.location document.location; //true// https://www.zhihu.com/search?typecontentq123location.href https://www.zhihu.com/search?typecontentq123.origin // 完整的urlhttps://www.zhihu.com.host // 页面的标准域名www.zhihu.com.hash // 服务器名称端口 例如‘www.zhihu.com:8080’#hash.pathname // url中#号后面的哈希值/search.search // url中[/]后面内容?typecontentq123.protocol // url中[?]后面内容https:.port // 协议[http:]; //端口号[ 80 | 8080 | ... ]方法
assign() 不会打开新窗口把请求 url 中的资源加载到当前窗口会给浏览器的History中增加一条历史记录 replace(url) 用 url 中的内容替换掉当前的 location 资源不会在浏览器的History中增加记录意味着用户不能使用回退按钮 reload() 重新加载当前 url 的内容当 reload(true)时会强制从服务器获取所有内容若没有参数重新加载时可能从浏览器缓存加载页面
拓展方向
location 本身 api 操作 assign VS replace 的区别 解析 url 中的查询字符串返回一个对象 思路可以通过正则的方式获取或者通过字符串分割的方式通过location.search获取查询字符串内容如果有[?]就截取[?]后面的内容然后通过[]进行分割成为[keyval1,keyval2]的形式通过[]对数组进行分割使用decodeURIComponent对 key 和 val 进行解码存放到对象中 路由相关: 跳转、参数、操作 页面能否返回history页面是否刷新hashreload、assign、replace 参数等 URI or URL 的区别? URI Uniform Resource Identifier - 统一资源标识符URL Uniform Resource Locator - 统一资源定位符
2.History
history.state.length; // 当前页面的状态 // 返回当前 会话 中的 history 个数方法
pushState(state, title, url) 给当前的 history 中添加一个状态浏览器地址会改变但是不会加载页面本质上页面还是停留在原来的页面 replaceState() 与 pushState 方法类似但是不会添加一个新的 state 到 history 中而是直接修改当前state
相关联的方法
window.onpopstate() 每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应 window 对象上触发调用history.pushState() 或者 history.replaceState() 不会触发 popstate 事件。popstate 事件只会在浏览器某些行为下触发比如点击后退、前进按钮(或者在 JavaScript 中调用 history.back()、history.forward()、history.go()方法)
例子
window.onpopstate function (event) {alert(location: document.location , state: JSON.stringify(event.state),);
};
//绑定事件处理函数.
history.pushState({ page: 1 }, title 1, ?page1); //添加并激活一个历史记录条目 http://example.com/example.html?page1,条目索引为1
history.pushState({ page: 2 }, title 2, ?page2); //添加并激活一个历史记录条目 http://example.com/example.html?page2,条目索引为2
history.replaceState({ page: 3 }, title 3, ?page3); //修改当前激活的历史记录条目 http://ex..?page2 变为 http://ex..?page3,条目索引为3
history.back(); // 弹出 location: http://example.com/example.html?page1, state: {page:1}
history.back(); // 弹出 location: http://example.com/example.html, state: null
history.go(2); // 弹出 location: http://example.com/example.html?page3, state: {page:3}3.navigator 浏览器系统信息大集合 clipboard 系统剪切板相关信息 userAgent 当前用户的设备信息 onLine 返回浏览器的在线状态 serial 返回串口对象Web Serial API 的入口点 bluetooth 系统蓝牙相关 …
4.screen 用来表示浏览器窗口外部的显示器的信息等 window.screen.deviceXDPI/deviceYDPI 屏幕实际的水平 DPI、垂直 DPI
三、浏览器事件
浏览器事件模型主要分为三个阶段
捕获阶段IE 事件由最外层元素(window),层层向内传递直到最具体的元素 目标阶段冒泡阶段网景 事件由最具体的元素(事件的触发者),层层向外传递传递给父节点直到 window 对象停止 1.addEventListener 第三个参数
el.addEventListener(event, function, useCapture)
// useCapture默认值false也就是默认冒泡
// true为捕获阶段2.阻断事件传播
event.stopPropagation() 阻断事件的传播但是无法阻止默认事件 event.stopImmediatePropagation() 如果有多个相同类型的事件监听函数绑定到同一个元素当该类型的事件触发时它们会按照被添加的顺序执行如果其中某个监听函数执行了此方法则当前元素剩下的监听函数将不会被执行
3.阻止默认行为
e.preventDefault() e.preventDefault()可以阻止事件的默认行为发生默认行为是指点击 a 标签就转跳到其他页面、拖拽一个图片到浏览器会自动打开、点击表单的提交按钮会提交表单等等因为有的时候我们并不希望发生这些事情所以需要阻止默认行为
拓展方向
性能方向
如事件委托的运用一个 ul 和多个 li点击 li 时改变背景颜色
{/*
ul classlistli1/lili2/lili3/li
/ul
*/
}
var list document.querySelector(list);function onClick(e) {var e e || window.event;if (e.target.tagName.toLowerCase() li) {// 业务逻辑...e.target.style.backgroundColor pink;}
}list.addEventListener(click, onClick, false);兼容性方向
如写一个兼容 IE 的事件绑定
先区别 IE 的不同之处
绑定事件的函数和传参不同: 使用 attachEvent绑定事件名要加on解绑时使用的函数和参数不同: 使用detachEvent解绑阻断时的不同: event.cancelBubble true阻止默认行为的不同: event.returnValue false
class BindEvent {constructor(el) {this.el el;}addEventListener(type, handler) {if (this.el.addEventListener) {this.el.addEventListener(type, handler, false);} else if (this.el.attachEvent) {this.el.attachEvent(on type, handler);} else {this.el[on type] handler;}}removeEventListener(type, handler) {if (this.el.removeEventListener) {this.el.removeEventListener(type, handler, false);} else if (this.el.detachEvent) {this.el.detachEvent(on type, handler);} else {this.el[on type] null;}}static stopPropagation() {if (e.stopPropagation) {e.stopPropagation();} else {e.cancelBubble true;}}static preventDefault() {if (e.preventDefault) {e.preventDefault();} else {e.returnValue false;}}
}四、网络请求
1.XMLHttpRequest
属性 responseText服务端响应的文本数据responseXML服务点响应的 xml 或者 html 类型数据status响应 HTTP 状态statusText响应 HTTP 状态描述readyState发出请求的状态码对应onreadystatechange事件 0:创建成功但是没有调用 open 方法1:open 方法被调用2:send 方法被调用3:loading下载中4:下载操作完成 timeout超时时间对应超时事件ontimeout,ontimeout 事件被弃用upload上传进度 方法 open() 初始化请求(method, url, async)async 表示是否异步操作默认 truesend() 发送请求数据get 请求时send 可以不传或者 nullabort() 中止已经发出的请求setRequestHeader() 设置请求头信息getRequestHeader() 获取指定响应头信息getAllResponseHeaders() 获取所有响应头信息
封装 XMLHttpRequest 请求
function ajax({ method get, url , params undefined }) {return new Promise((resolve, reject) {let xhr new XMLHttpRequest();if (method.toLowerCase() get params ! undefined) {url url ? params;}xhr.open(method, url, true);xhr.onreadystatechange function () {if (xhr.readyState 4) {if (xhr.status 200) {resolve(xhr.responseText);} else {reject(xhr.status);}}};if (method.toLocaleLowerCase() get) {xhr.send();} else {xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded);xhr.send(params);}xhr.onerror (err) reject(err);xhr.timeout () reject(timeout);// progress事件可以报告长时间运行的文件上传xhr.upload.onprogress (p) {console.log(Math.round((p.loaded / p.total) * 100) %);};});
}2.fetch
方法fetch(url{} init 对象 )返回 Promise 对象只支持异步响应通过 response 对象获取 fetch().then((response){}).catch((){})response 对象混入了 body提供了 5 个方法将 ReadableStream 转存到缓冲区的内存里将缓冲区转换为 js 对象通过 Promise 返回response.text() //转为 textresponse.json() //转为 jsonresponse.formData()response.arrayBuffer()response.blob() 不支持超时设置 但是可以使用promisesetTimeout进行控制 默认不携带cookies但是可以设置 fetch(url, {credentials: include});omit 不发送 cookiesame-origin 同源发送 cookie默认include 都发送 cookie resolve 若发生在网络通信正常404500也是 resolve .catch()也不会被执行。reject 只发生在网络通信异常想要精确的判断 fetch 是否成功需要包含 promise resolved 的情况此时再判断 response.ok 是不是为 true 需要借用 AbortController 中止 fetch
// resolve若发生在网络通信正常404500也是resolve
fetch(http://domain/service, {method: GET,
}).then((response) {// 想要精确的判断 fetch是否成功// 需要包含 promise resolved 的情况此时再判断 response.ok是不是为 trueif (response.ok) {return response.json();}throw new Error(Network response was not ok.);}).then((json) console.log(json))// .catch()也不会被执行.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
// signal用于支持AbortController中断请求
const controller new AbortController();
// AbortController接口表示一个控制器对象
// 允许你根据需要中止一个或多个 Web请求
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();3.Http 状态码和 Header
1.状态码 100 信息性|200 成功|300 重定向|400 客户端错误|500 服务器错误 [1|2|3]xx
101 切换协议200 Ok301 永久重定向设备会缓存302 临时重定向以前是临时转移已经不推荐使用了建议使用 307307 临时重定向 如果是 POST/DELETE 过来的会继续使用302 只会使用 get 304 (Not Modified)服务器文件未修改,协商缓存308 永久重定向
4xx
400 客户端请求有语法错误不能被服务器识别403 服务器受到请求但是拒绝提供服务可能是跨域也可是权限不够404 请求的资源不存在405 请求的 method 不允许
5xx
500 服务器发生不可预期的错误
2.字段
Content-Length 发送给接收者给 Body 内容长度字节 一个 Byte 是 8bitutf-8 编码的字符是 1-4 个字节 User-Agent客户端特性的字符串Content-Type 媒体类型Origin描述请求来源地址Accept 建议服务端返回何种媒体类型 */*表示所有类型默认text/html,application/json Accept-Encoding 建议服务端发送什么编码压缩算法deflate,gzip;q1.0,*;q0.5 Accept-Language 建议服务端传递那种语言Referer 告诉服务端打开当前页面的上一张页面的 URL如果是 ajax 请求那么就告诉服务端发送请求的 URL 的什么 非浏览器环境有时候不发生 Referer或者虚拟 Referer,通常是爬虫常用来做用户行为分析 Connection 决定链接是否在当前事务完成后关闭http1.0 默认是 closehttp1.1 默认是 keep-alive 4.拓展方向
如何应对网络不稳定波动的情况
失败了重发指数补偿
const request (url) {let resolved false;let t 1;return new Promise((resolve, reject) {// Promise.race([// fetch(url),// wait(100, () fetch(url)),// wait(200, () fetch(url)),// wait(400, () fetch(url)),// wait(800, () fetch(url)),// wait(1600, () fetch(url)),// ])function doFetch() {if (resolved || t 16) return;fetch(url).then((resp) resp.text()).then((data) {if (!resolved) {resolved true;resolve(data);}});setTimeout(() {doFetch();t * 2;}, t * 100);}doFetch();});
};如何处理并发请求
若相同的请求多次发送会照成带宽的浪费处理思路做缓存因为请求具有时效性所以不能做永久缓存相同的请求在一定的时间内只发生一次 使用w保存请求信息若同一时间发送多次相同对请求使用w[hash].resolves保存 resolve 函数 当请求函数w[hash].func发送成功执行 resolves 中的函数保证每次请求都有响应信息
import fetch from node-fetch;
function hash(...args) {return args.join(,);
}
function window_it(fn, time 50) {let w {}; // 时间窗口let flag false;return (...args) {return new Promise((resolve, reject) {if (!w[hash(args)]) {w[hash(args)] {resolves: [],func: fn,args,};}if (!flag) {flag true;setTimeout(() {Object.keys(w).forEach((key) {console.log(run ${key});const { func, args, resolves } w[key];func(...args).then((res) res.text()).then((data) {resolves.forEach((r) {console.log(resolve ${key});r(data);});flag false;delete w[key];});});}, time);}w[hash(args)].resolves.push(resolve);});};
}const request window_it(fetch, 20);
request(http://www.baidu.com).then((txt) console.log(txt.length));
request(http://www.baidu.com).then((txt) console.log(txt.length));
request(http://www.baidu.com).then((txt) console.log(txt.length));request(http://www.zhihu.com).then((txt) console.log(txt.length));
request(http://www.zhihu.com).then((txt) console.log(txt.length));
request(http://www.zhihu.com).then((txt) console.log(txt.length));往期精彩文章
leetcode-js刷题记录数据结构docker下YApi部署教程-支持swagger数据导入带你深入理解什么叫js闭包使用Object.defineProperty进行数据劫持,实现响应式原理-剖析vue2.0前端性能优化之rel“prefetch“预/懒加载功能前端唤起相机的方法H5JS