浏览器内置对象
什么是浏览器对象模型
BOM:Browser Object Model (浏览器对象模型),浏览器模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构,就是浏览器提供的API。
其主要对象又:
- window 对象 —— BOM 的核心,是 JS 访问浏览器的接口,也是 ES 规定的 Global 对象。
- location 对象:提供当前窗口中的加载的文档有关的信息和一些导航功能。既是 window 对象熟悉,也是 document 的对象属性。
- navigation 对象:获取浏览器的系统消息。
- screen 对象:用来表示浏览器窗口外部的显示器的信息等。
- history 对象:保存用户上网的历史信息。
Window 对象
windows 对象是整个浏览器对象模型的核心,其扮演着既是接口又是全局对象的角色。
窗口大小
窗口位置
核心常用
Location 对象
Navigation 对象
navigation 接口表示用户代理的状态和标识,允许脚本查询它和注册自己进行一些活动。
History 对象
浏览器事件模型详解
详解浏览器事件捕获,冒泡
浏览器事件模型中的过程主要分为三个阶段:捕获阶段、目标阶段、冒泡阶段。
第三个参数
要注意addEventListener 的第三个参数,如果为true,就是代表在捕获阶段执行。如果为false,就是在冒泡阶段进行。
// 冒泡
window.addEventListener('click', function() {
// 点击逻辑
}, false);
// 捕获
window.addEventListener('click', function() {
// 点击逻辑
}, true)
阻止事件传播
-
e.stopPropagation()
大家经常听到的是阻止冒泡的传播,实际上这个方法还能阻止捕获阶段的传播。 -
e.stopImmediatePropagation()
如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果某个监听函数执行了 e.stopImmediatePropagation(),则当前元素剩下的监听函数讲不会在执行。
阻止默认行为
- e.preventDefault()
可以阻止事件的默认行为发生,默认行为是指:点击a标签就跳转到其他页面、拖拽一个图片到浏览器会自动打开、点击表单的提交按钮会提交表单等等,因为有时候我们希望发生这些事情,所以需要阻止默认行为。
面试实战一:ul + li
要求:点击每个li alert对应的索引。(伪代码实现)
<html>
<body>
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
// ... (上万个)
</ul>
</body>
<script>
// 方案1 (缺点:频繁操作dom,性能差)
const liList= document.getElementsByTagName("li");
for(let i = 0; i < liList.length; i++) {
liList[i].addEventListener('click', function(e){
alert(`内容为:${e.target.innerHtml}, 索引为${i}`);
}, false)
}
// 方案2 (使用事件委托,解决方案1的缺点)
const ul = document.getElementById('ul');
ul.addEventListener('click', function(e) {
const target = e.target
if (target.tagName.toLowerCase() === 'li') {
const liList = this.querySelectorAll("li");
const index = Array.prototype.indexOf.call(liList, target);
alert(`内容为${target.innerHtml},索引为${index}`);
}
}, false);
</script>
</html>
面试实战二:封装多浏览器兼容的绑定事件函数
class BomEvent {
constructor(element){
this.element = element;
}
addEvent(type, handler) {
if (this.element.addEventListener) {
this.element.addEventListener(type, handler, flase);
} else if(element.datachEvent) {
this.element.detachEvent('on' + type, handler);
} else {
this.element['on' + type] = null;
}
}
removeEvent(type, handler) {
if (this.element.removeEnentListener) {
this.element.removeEnentListener(type, handler, false);
} else if (element.datachEvent) {
this.element.detachEvent('on' + type, handler);
} else {
this.element['on' + type] = null;
}
}
}
// 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
function stopPropagation(ev) {
if (ev.stopPropagation) {
ev.stopPropagation(); // 标准w3c
} else {
ev.cancelBubble = true; // IE
}
}
// 取消事件的默认行为
function preventDefault(event) {
if (event.preventDefault) {
event.preventDefault(); // 标准w3c
} else {
event.returnValue = false; // IE
}
}