【前端面试】四、DOM和BOM
目录
文档对象模型(DocumentObjectModel,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口。在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象的标准模型就称为DOM。关于dom的api有什么参考回答:节点创建型api,页面修改型API,节点查询型API,节点关系型api,元素属性型api,元素样式型api等
1. BOM属性对象方法
location对象:
- location.href--返回或设置当前文档的URL
- location.search--返回URL中的查询字符串部分。例如http://www.dreamdu.com/dreamdu.php?id=5&name=dreamdu返回包括(?)后面的内容?id=5&name=dreamdu
- location.hash--返回URL#后面的内容,如果没有#,返回空
- location.host--返回URL中的域名部分,例如www.dreamdu.com
- location.hostname--返回URL中的主域名部分,例如dreamdu.com
- location.pathname--返回URL的域名后的部分。例如http://www.dreamdu.com/xhtml/返回/xhtml/
- location.port--返回URL中的端口部分。
- location.protocol--返回URL中的协议部分。
- http:location.assign--设置当前文档的URL
- location.replace()--设置当前文档的URL,并且在history对象的地址列表中移除这URLlocation.replace(url);
- location.reload()--重载当前页面
history对象:
- history.go()--前进或后退指定的页面数history.go(num);
- history.back()--后退一页
- history.forward()--前进一页
Navigator对象:
- navigator.userAgent--返回用户代理头的字符串表示(就是包括浏览器版本信息等的字符串)
- navigator.cookieEnabled--返回浏览器是否支持(启用)cookie
参考文献:DOM的三个级别_一只小废物变小怪物的博客-CSDN博客_dom 属性级别
2. 事件流
事件流:HTML与js交互是通过事件驱动实现,事件流描述的是从页面中接收事件的顺序
事件发生的三个阶段:
- 事件捕获:事件从Document节点自上而下向目标节点传播的阶段
- 目标阶段:真正的目标节点正在处理事件的阶段
- 冒泡阶段:事件从目标节点自下而上向Document节点传播的阶段 ;浏览器默认冒泡,focus/blur不支持冒泡,可根据event.bubbles判断事件是否支持冒泡
事件模型常用方法:
event.stopPropagation:阻止捕获和冒泡阶段中当前事件的进一步传播
event.stopImmediatePropagation:阻止调用相同事件的其他侦听器,阻止冒泡
event.preventDefault:取消该事件而不停止事件的进一步传播,阻止事件的默认行为
event.target:指向事件触发的元素,在事件冒泡过程中这个值不变
event.currentTarget:指向事件绑定的元素
事件执行顺序:
DOM标准事件模型中,先捕获后冒泡
如果DOM节点同时绑定了两个事件监听函数,一个用于捕获,一个用于冒泡,绑定在被点击元素的事件是按照代码添加顺序执行的
要实现先冒泡后捕获,对于同一个事件监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件先暂缓执行,直到冒泡事件被捕获后再执行捕获事件
阻止冒泡:
let sonEl = document.querySelector('.son')
let fatherEl = document.querySelector('.father')
sonEl.addEventListener("click", (event) => {
console.log('son事件');
// event.stopPropagation() // 阻止事件冒泡,'father事件'将不会打印
}, true) // true在事件捕获执行,false在事件冒泡执行
fatherEl.addEventListener("click", () => {
console.log('father事件');
})
3. 事件委托
原理:将当前节点上的事件绑定在父节点上进行事件监听,通过事件冒泡处理子事件,event.target.nodeName判断事件触发元素。减少事件绑定和内存消耗,提高程序性能,尤其在动态添加子元素的时候。
应用场景:大量同级元素添加同一类事件,动态绑定事件。比如需要为动态列表的每个列表项都添加点击事件,ul 上绑定事件来监听 li
事件代理在捕获阶段的实际应用:在父元素阻止事件向子元素传播,也可代替子元素执行某些操作
// 通过event.target获取点击的哪一个li
let ul = document.querySelector('ul');
ul.onclick = (event) => {
event = event || window.event;
if(event.target.nodeName == 'LI') {
alert(event.target.innerHTML)
}
}
let btn =document.querySelector('#btn');
btn.onclick = () => {
let li = document.createElement('li');
li.textContent = ul.children.length;
ul.appendChild(li)
}
4. 事件监听
addEventListener(event,function,useCapture):event指定事件名;function指定事件触发时执行的函数;useCapture指定事件是否在捕获(true)或冒泡(false)阶段执行
5. mouseover和mouseenter的区别
mouseover:当鼠标移入元素或子元素都会触发事件,会冒泡,对应mouseout
mouseenter:当鼠标移入元素本身(不含元素子元素)触发事件,不会冒泡,对应mouseleave
6.路由原理
- history 实现
history 提供了 pushState 和 replaceState 两个方法,这两个方法改变 URL的 path 部分不会引起页面刷新
history 提供类似 hashchange 事件的 popstate 事件,但popstate 事件有些不同:
1通过浏览器前进后退改变URL时会触发popstate 事件
2.通过pushState/replaceState或<a>标签改变 URL不会触发 popstate 事件
3.好在我们可以拦截 pushState/replaceState的调用和<a>标签的点击事件来检测 URL变化
4.通过js调用history的back,go,forward方法可触发该事件
所以监听URL变化可以实现,只是没有 hashchange 那么方便
- hash 实现
hash 是URL中hash(#)及后面的那部分,常用作描点在页面内进行导航,改变URL中的 hash 部分不会引起页面刷新
通过 hashchange 事件监听 URL的变化,改变 URL的方式只有这几种
1.通过浏览器前进后退改变 URL
2.通过<a>标签改变 URL
3.通过window.location改变URL