浏览器的BOM

122 阅读2分钟

**一. 浏览器运行态下的JS(BOM DOM ECMAScript) **

1. ECMAScript 主要负责基础逻辑 数据处理
2. DOM 浏览器视窗内文本的相应操作
3. BOM 对于浏览器本身区域能力的操作

** 二. BOM**

1. location:
    .href: 完整路径,路径栏所有。‘https://www.baidu.com/search?eat=mantou#num’
    .origin: 域名部分 ‘https://www.baidu.com’
    .protocol: 协议部分 ‘https:’
    .post: 不包含协议的域名 ‘www.baidu.com’
    .port: 端口号 ‘’
    .pathname: 域名后的路径名 ‘/search/’
    .search: 参数 不带hash ‘?eat=mantou’
    .hash: '#num'
    .assign(''): 跳转到指定path 替换pathname的值
    .replace(''): 同上,同时会替换浏览地址 导致不能返回,没有上次的历史记录。
    .reload(): 刷新
    .toString(): 产出当前地址字符串
    
2. history:
    .state: 存储当前页面的状态
    .pushState 、replaceState 通过这两种方法来实现 不刷新浏览器跳转路由。对历史记录进行一个存储
   
3. navigator: 浏览器信息集合
    .userAgent: 当前用户的环境信息
        可以读取信息 根据不同环境做一些浏览器兼容和上报信息的问题
        
4. screen: 荧幕
    window的视窗判断: 
       全局入口处获取:
        window.innerHeight
        window.innerWidth
        
        文本处获取:
            document.documentElement.clientHeight
            document.documentElement.clientWidth
            document.body.clientHeight
            document.body.clientWidth
       网页视图的size
           offsetHeight = clientHeight + 滚动条 + 边框
           document.documentElement.offsetHeight
           document.documentElement.offsetWidth
           document.body.offsetHeight
           document.body.offsetWidth
           
   el.getBoundingClientRact()元素上下左右的位置
   

三. Event事件模型

1. 冒泡: 从内向外 冒泡
2. 捕获: 从外向内 捕获
3. 如何阻止事件的冒泡?
    event.stopPropagation()
    
`   
   手写兼容性事件绑定
   IE - attachEvent vs addEventlistener
   区别: attachEvent 事件名要加 ‘on’
   a. 执行顺序 attachEvent 后绑定先执行 addEventlistener 先绑定先执行
   b. 解绑 detachEvent removeEventlistener
   c. 阻断 event.cancelBubble = true vs event.stopPropagetion()
   d. 阻止默认事件 event.returnValue = false vs event.preventDefault()
   
   class binEvent {
       constructor(element) {
           this.element = element
       }
       // 绑定
       addEventListener = (type, handle) => {
           if(this.element.addEventlistener) {
               this.element.addEventlistener(type, handle)
           } else if(this.element.attachEvent) {
               this.element.attachEvent('on' + type , () => {
                   handle.call(element)
               })
           } else {
               this.element['on' + type] = handle
           }
       }
       // 解绑
       removeEventListener = (type, handle) => {
           if(this.element.removeEventlistener) {
               this.element.removeEventlistener(type, handle)
           } else if(this.element.detachEvent) {
               this.element.detachEvent('on' + type , () => {
                   handle.call(element)
               })
           } else {
               this.element['on' + type] = null
           }
       }
       // 阻断
       static stopPropagation(e) {
           if(e.stopPropagation) {
               e.stopPropagation()
           } else {
               et.cancelBubble = true
           }
       }
       // 默认拦截
       static preventDefault(e) {
           if (e.preventDefault) {
               e.preventDefault()
           } else {
               e.returnValue = false
           }
       }
   }
`

四. 网络层(封装ajax)

`  
    function ajax (options) {
        const { url, methods, data, timeout, async } = options;
        const xhr = XHLHttpRequest()
        
        // 配置超时时间
        if(timeout) {
            xhr.timeout = timeout
        }
        return new Promise((resolve, reject) => {
            // 成功
            xhr.onreadystatuschange = () => {
                if(xhr.readyState === 4) {
                    if(xhr.status >= 200 && 
                        xhr.status < 300 || 
                        xhr.status === 304) {
                            resolve(xhr.responsText)
                      } else {
                          reject()
                      }
                }
            }
            // 失败
            xhr.onerror = () => reject()
            xhr.timeout = () => reject('timeout')
            
            // 传参处理
            let params = []
            let encoedData = ''
            if (data instanceof Object) {
                for(let key in data) {
                    params.push(
                        encodeURIComponent(key) 
                        + '=' + 
                        encodeURIComponent(data[key]) 
                    )
                }
                encoedData = params.join('&')
            }
            
            // 判断method链接
            if(methods === 'get') {
                const index = url.indexOf('?')
                if(index === -1) {
                    url += '?'
                } else if(index !== url.length-1) {
                    url += '&'
                }
                rul += encoedData
            }
            
            // 建立链接
            xhr.open(methods, url, async)
            
            // 发送请求
            if(methods === 'get') {
                xhr.send(null)
            } else {
                xhr.setRequestHeader (
                    'content-type': 'application/x-www-from-urlencoded'
                    // 设置传送的内容类型
                )
                xhr.send(encodeData)
            }
        })
    }
`