BOM与DOM

132 阅读4分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

BOM

1.BOM

浏览器对象模型,核心是window

2.BOM组成

  1. Window
  2. Navigator:客户端浏览器的信息
  3. History: 包含网页访问过的URL
  4. Screen
  5. Location: URL

3.window

  1. pageXOffset/pageYOffset 可以设置但是并不能操纵
  2. name 网页或者框架的名字
  3. confirm()/alert()/prompt()
  4. close()
  5. open(url, name, features, replace) name必须写

4.Navigator

  1. onLine 在线或者脱机(离线缓存)
  2. userAgent(浏览器的信息)
  3. cookieEnabled cookie是否启用

5.History

  1. back()
  2. forward()
  3. go(n)
  4. length

6.Location

  1. url组成 : 协议名 域名 路径 参数 锚点

www.baidu.com/s?key=value…

  1. protocol
  2. hostname
  3. pathname
  4. search
  5. hash (不会造成网页刷新)

上述修改必须带符号

  1. href 完整url路径

单页面应用:利用hash

  1. assign() 加载新文档
  2. reload() 不填或者填false,取缓存

7.Screen

DOM

1.实现异步加载JS的方式

  1. defer异步加载

defer能异步加载页面级js,而且只有当dom==解析==(DOM Tree建立)完毕才能执行
只有==IE==才能用

  1. async异步加载

只能加载外部js,加载完就能执行

  1. 创建script
function loadScript (url, callBack) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    document.head.appendChild(script);//插入后只能调用执行
    //由于需要加载完成后才能调用执行,因此需要检测什么时候结束
    //IE上有一个状态码 readyState(readystatechange)
    //其余直接检测load
    script.onreadystatechange = function () {
        if (document.readyState === 'complete' || document.readyState === 'loaded') {
            tools[callback]();
        }
    }else {
        script.onload = function () {
            tools[callback]();
        }
    }
    //这个放在下面防止加载太快,onreadystatechange监控不到变化
    script.src = url; //只加载
}

/*
* 为什么要使用tools[callback]()
*/
loadScript('demo.js', test);
//上述调用会报错为什么?
//因为demo.js还没被加载,因此test函数不存在
//那么实参就只能为string类型
//而且一般标准类库都是这种形式:

var tools = {
    test : function () {},
    other : function () {}
}

1.鼠标事件

  • contextmenu 右键菜单事件
  • mousedown
  • mouseup
  • mousumove
  • mouseenter
  • mouseleave
  • 触发顺序:mousedown mouseup click(仅限于左键)
  • 如何区分左右键
    1. 只有mouseup/mousedown才可以区分
    2. mouseup/mousedown触发时的事件对象MouseEvent有一个button属性
    3. button=0/1/2分别代表左键/滚轮/右键
    4. DOM3级规定click只能监听左键
  • 如何区分拖拽和click
//利用时间差
var firstTime = 0,
    lastTime = 0,
    isDrag = false;
    
    document.onmousedown - function () {
        firstTime = new Date().getTime();
    }
    document.onmouseup - function () {
        lastTime = new Date().getTime();
        if (lastTime - firstTime > 200) {
            isDrag = true;
        }
    }
    document.onclick - function () {
        if (!isDrag) {
            //body
        }
    }

2.键盘事件

  • keydown
  • keypress
  • keyup
  • 触发顺序:keydown keypress keyup
  • keydown与keypress 区别
    1. keydown响应任何按键,但是一般用于区分方向键
    2. keydown which属性区分方向键
    3. keypress只能响应ASCII码,并且能区分(charCode属性)

3.文本事件

  • input 文本改变触发
  • change触发方式是比较focus和blur两个状态的值是否相同

4.加载事件

  • load
  • scroll

1.事件流

事件流描述的是从页面中接收事件的顺序

2.DOM事件流

事件捕获阶段、处于目标阶段、事件冒泡阶段

//html dom树结构
/*
Document
    Element html
        Element body
            Element div
*/
//事件捕获阶段截止到body
  • 事件冒泡:结构上嵌套元素从子元素冒泡向父元素
  • 事件捕获:

setCapture(IE下面处理捕获)

3.阻止冒泡和阻止默认行为

1.事件委托的例子

  1. 典型案例:扫雷
    如果没有事件委托,我们会这样处理扫雷游戏,给每个格子添加一个click事件,但是问题来了,每个格子的事件处理函数都是一样的,那如果雷盘大到一定程度,那我们重复绑定就会造成大量的空间损耗。
  2. 子元素个数会动态增加,难道每动态增加一个子元素,就重新再为他绑定一次事件??

2.事件委托

很明显上两种情况利用我们现在学的知识做起来对性能的伤害和繁琐程度都不是我们想要的。

2.1事件委托的原理

冒泡原理配合event对象
给子元素的父元素绑定事件,当子元素触发事件时通过冒泡冒泡到父元素的事件处理函数上。
那怎么找到是==哪个子元素==触发的事件那?
event.targat代表触发事件的源元素

<ul>
<li class='clickme'></li>
<li class='nodotclickme'></li>
</ul>
ul.addEventListener('click', fn, false)
function fn(e) {
    var event = e || window.event;
    console.log(e.target.className)
}
//当你点击第一个就会输出clickme

event上面还有一个属性,可以找到注册这个事件的监听对象(event.currentTarget)