BOM/DOM/ECMAScript
(function(conext,undefined){
const _class = ['js','browser','vue'];
//1向全局作用域存储一个class变量
window.classArr = _class.map(item => item);
//2获取当前页面地址
const _url = location.href
//3改变页面标题
document.title='zzzzjj'
//4获取渲染节点
document.getElementById('app');
})(this)
//ECMAscript 处理基础逻辑、数据处理
//BOM 对浏览器本身功能区域的汇总处理
//DOM 对浏览器视窗内的HTML文本的相关操作
一、BOM
1、 location
location.href -> https://mp.weixin.qq.com/cgi-bin/wx?token=&lang=zh_CN
.origin 取前半部分主地址 https://mp.weixin.qq.com
.protocol 协议 https
.host 主域名 mp.weixin.qq.com
.port 端口 localhos://9090
.pathname 接口 /wx
.search 接口后参数 ?token=&lang=zh_CN
.hash 单页应用下的切换
location.assign(‘
u
r
l
′
)
跳转到指定
p
a
t
h
,替换原有路由
.
r
e
p
l
a
c
e
(
′
{url}') 跳转到指定path,替换原有路由 .replace('
url′)跳转到指定path,替换原有路由.replace(′{url}’) 跳转并替换路由,替换浏览历史
.reload()
.toString() 产出当前地址 =》 字符串
2 history
history.state ->存储当前页面状态
.pushState()-> 跳转到指定状态页
.replaceState() 替换当前状态
history和hash 利弊分析 =》两种路由方式的考察 路径与浏览器渲染机制考联系
3 Navigator
navigator.userAgent //获取当前用户环境变量
//UA读取信息,如安卓版本=》浏览器兼容,微信还是app
4 screen
表示显示区域 屏幕
window.innerHeight
window.innerWidth
文本处获取
document.documentElement.clientHeight(/width)
document.body.clientHeight(/width)
网页size -》offsetHeight= clientHeight+滚动条+边框
document.documentElement.offsetHeight(offsetWidth)
document.body.offsetHeight(/width)
定位
scrollLeft / scrollTop 距离常规左/上滚动的距离
offsetLeft / offsetTop 距离常规左/上相对距离
全局获取滚动定位
el.getBoundingClientRect()
.top .left .bottom .rtght
兼容性问题IE多出2px
三、event事件模型
<div id ="app">
<p id ="dom">click</p>
</div>
// 冒泡-ms : p-> div->body->HTML -> document
// 捕获- ns:document ->Html ->body ->div -> p
el.addEventListener(event,function,useCaptrue);//默认useCaptrue
//1 如何阻止事件传播
event.stopPropagation();
//注意:无论向上还是向下都是可以阻止的=》无法阻止默认事件发生-》a标签跳转
//2、如何阻止默认事件传播
event.preventDefalut();
//3 相同节点绑定多个同类事件,如何阻止
event.stopImmediatePropagetion();
//4 手写绑定事件
attachEvent & addEventListener
//区别
//a 传参 attachEvent对于事件名加'on'
//b 执行顺醋 attachEvent -后绑定执行;addEventListener-先绑定执行
//c 解绑 detachEvent 、 removeEleventListener
//d 阻断 e.cancelbubble = true / e.stopPropagetion()
//e 默认事件打断 e.returnValue /e.preventDefalut
class bindEvent{
constructor(element){
this.elememt = element
}
}
addEvenListener=(type, handler){
if(this.element.addEventListener){
this.elememt.addEventListener(type,handler,false);
}else if(this.elememt.attachEvent){
const elememt = this.element
this.elememt.attachEvent('on'+type,()=>{});
}else{
this.elememt['on'+type] = handler
}
}
removeEvenListener =(type , handler) => {
if(this.elememt.removeEvenListener){
this.elememt.removeEvenListener(type , handler, false);
}else if(this.elememt.detachEvent){
const elememt = this.elememt;
this.elememt.detachEvent('on'+type , ()=>{
})
}else{
this.elememt['on'+type]=null
}
}
static stopProoagetion(e){
if(e.stopProoagetion){
e.stopProoagetion();
}else{
e.cancelBubble = true
}
}
static preventDefalut(e){
if(e.preventDefalut){
e.preventDefalut();
}else{
e.returnValue = true
}
}
//性能优化 事件代理
<ul class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div class="content"></div>
var list = document.querySelector(".list")
var li =list.getElementsByTagName("li")
var content = document.querySelector(".content")
// 老方法遍历
for (var n =0; n>li.length;n++) {
li[n].addEventListener("click",function){
}
}
// 代理后 利用冒泡
function onClick (e) {
var e = e || window.event;
if(e.targent.nodeName.toLowerCase()==="li"){
const liList = this.querySelectorAll("li");
index = Array.prototype.indexOf.call(liList , target);
}
}
list.addEventListener("click",onClick,false);
四 网络层
// 实例化实例化实例化实例化实例化实例化
const xhr = new XMLHttpRequest();
// 初始化连接
// xhr有一个open方法
// open 5个参数
// method - get/post
// url - 请求的地址
// anync - 是否异步请求
// send发送请求
// 内容:post - 将请求体的参数传入;get - 可以不传 or 传入null
xhr.send(data)
// 接收
xhr.readyState
// 0 - 尚未调用open
// 1 - 已调用 open
// 2 - 已发送请求 已调用send
// 3 - 已接收到请求返回的数据
// 4 - 请求已完成
xhr.onreadystatechange = () =>{
if (xhr.readyState === 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('失败' + res)
)
// 实现
function ajax (options) {
const{
url,
method,
async,
timeout,
data
}=options;
}
const xhr = new XMLHttpRequest();
return new Promise((resolve,reject) =>{
// 1、阶段状态处理
// 成功
xhr.onreadystatechange =() =>{
if(xhr.readyState===4){
if(xhr.status >= 200 && xhr.status < 300 ||xhr .status ===304){
resolve && resolve(xhr.responseText);
}else{
reject && reject();
}
}
}
// 失败 超时、报错
xhr.ontimeout = () => reject && reject("超时")
xhr.onerror = () =>reject && reject(err);
// 2、传参处理
let _params = [];
let encodeData;
if(data instanceof Object){ //没有data,返回是一个object对象
for (let key in data){
// 参数拼接转码成字符串
_params.push(encodeURIComponent(key) +'=' +encodeURIComponent(data[key]))
}
encodeData = _params.join('&') //拼接成字符串
}
// get类型处理 参数拼接在url上
if(method === 'get'){
const index = url.indexOf('?'); //判断URL是否有search
if(index === -1) url+= '?'; //没有search的情况
else if(index !== url.length -1) url += '&';
url += encodeData;
}
// 3、初始换连接
xhr.open(method,url ,async)
// 4、发送
if(method=== 'get'){
xhr.send(null)
}else{
xhr.setRequestHeader(
'content-type','application/x-www-form-urlencodeed;charset=UTF-8'
)
xhr.send(encodeData);
}
})