持续更新……
BOM
概念:BOM(Brower Object Model)
是浏览器对象模型。主要处理浏览器窗口和框架,描述与浏览器进行交互的方法和接口,可以对浏览器窗口进行访问和操作,比如弹出新的窗口、回退历史记录等。
BOM对象
Window JavaScript
层级中的顶层对象,表示浏览器窗口。同时 window 也是网页中的全局对象。Navigator
代表当前浏览器的信息,通过该对象可以识别不同的浏览器。History
包含了浏览器窗口访问过的URL。Location
包含了当前URL的信息,通过 Location 可以获取地址栏信息,或者操作浏览器跳转页面。Screen
包含客户端显示屏的信息。
注意:这些 BOM 对象都是作为 window 对象的属性保存的,可以通过window对象来使用,也可以直接使用。比如,可以使用
window.location.href
,也可以直接使用location.href
,二者是等价的。document
也是在window
中保存的
常用的对象
1、navigator
一般我们只会使用navigator.userAgent
来获取浏览器的信息。
代码示例如下:
<script>
// 获取当前浏览器的userAgent
var UA = navigator.userAgent;
console.log('ramona当前浏览器的userAgent为:' + UA);
if (/firefox/i.test(UA)) {
alert('火狐浏览器');
} else if (/chrome/i.test(UA)) {
alert('Chrome浏览器');
} else if (/msie/i.test(UA)) {
alert('IE浏览器');
} else if ('ActiveXObject' in window) {
alert('IE 11 浏览器');
}
</script>
我们也可以直接在浏览器控制台上输入:navigator.userAgent
,查看到如下结果:
另外我们还可以在电脑上模拟移动端浏览器的场景。如下图方式操作:
不同浏览器的userAgent
iOS 版微信浏览器:
Mozilla/5.0 (iPhone; CPU iPhone OS 9_3 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13E233 MicroMessenger/6.3.15 NetType/WIFI Language/zh_CN
Android 版微信浏览器:
Mozilla/5.0 (Linux; Android 5.0.1; GT-I9502 Build/LRX22C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 MicroMessenger/6.1.0.78_r1129455.543 NetType/WIFI
iOS 版本QQ浏览器:
Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_2 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) Mobile/15C202 QQ/7.3.5.473 V1_IPH_SQ_7.3.5_1_APP_A Pixel/1125 Core/UIWebView Device/Apple(iPhone X) NetType/WIFI QBWebViewType/1
Android 版 QQ浏览器:
Mozilla/5.0 (Linux; Android 4.4.2; PE-TL20 Build/HuaweiPE-TL20; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/043807 Mobile Safari/537.36 V1_AND_SQ_7.3.2_762_YYB_D QQ/7.3.2.3350 NetType/WIFI WebP/0.3.0 Pixel/1080
2、History
History对象可以用来操作浏览器的向前或向后翻页。
常见的属性和方法代码示例如下:
history.length // 获取浏览器历史列表中的 url 数量,只是统计当次的数量,如果浏览器关了,数量会重置为1
history.back(); // 用来回退到上一个页面,作用和浏览器的「回退按钮」一样
history.forward(); // 用来跳转下一个页面,作用和浏览器的「前进按钮」一样
history.go( 1 ); // 向前跳转一个页面,相当于 history.forward()
history.go( 0 ); // 刷新当前页面
history.go( -1 ); // 向后跳转一个页面,相当于 history.back()
3、Location
Location 对象封装了浏览器地址栏的 URL 信息。
常见的属性和方法代码示例如下:
console.log(location.href); // 获取当前页面的url 路径
location.href = 'www.baidu.com'; // 跳转到指定的页面链接。通俗理解就是:跳转到其他的页面
location.assign(str);
location.reload(); // 重新加载当前页面
location.reload(true); // 在方法的参数中传递一个true,则会强制清空缓存刷新页面
location.replace(); // 使用一个新的页面替换当前页面,调用完毕也会跳转页面。但不会生成历史记录,不能使用「后退按钮」后退
详情参考:https://github.com/huyaocode/webKnowledge/blob/master/%E5%89%8D%E7%AB%AF%E5%9F%BA%E7%A1%80/JS/BOM.md
DOM
概念:通俗的说DOM就是浏览器为JavaScript提供的一系列接口(通过window,document提供的),通过这些接口我们可以操作web页面。比如让盒子移动、变色、轮播图等。DOM不是编程语言,是文档对象模型,该模型独立于编程语言。
API (web 或 XML 页面) = DOM + JS (脚本语言)
节点
节点(Node):构成 HTML 网页的最基本单元。网页中的每一个部分都可以称为是一个节点,比如:html标签、属性、文本、注释、整个文档等都是一个节点。
虽然都是节点,但是实际上他们的具体类型是不同的。常见节点分为四类:
文档节点(文档):整个 HTML 文档。整个 HTML 文档就是一个文档节点。
元素节点(标签):HTML标签。
属性节点(属性):元素的属性。
文本节点(文本):HTML标签中的文本内容(包括标签之间的空格、换行)。
节点的类型不同,属性和方法也都不尽相同。所有的节点都是Object。
DOM解析过程
HTML加载完毕,渲染引擎会在内存中把HTML文档,生成一个DOM树,getElementById是获取内中DOM上的元素节点。然后操作的时候修改的是该元素的属性。在HTML当中,一切都是节点。
DOM操作
1、创建新节点
方法 | 描述 |
---|---|
createDocumentFragment() | 创建一个 DOM 片段 |
createElement() | 创建一个具体的元素 |
createTextNode() | 创建一个文本节点 |
2、修改节点
方法 | 描述 |
---|---|
appendChild() | 添加子元素 |
removeChild() | 删除子元素 |
replaceChild() | 替换子元素 |
insertBefore() | 插入子元素 |
cloneNode(true/false) | 复制/克隆节点(不带参数/带参数false:只复制节点本身,不复制子节点;带参数true:既复制节点本身,也复制其所有的子节点) |
3、DOM查找
元素节点的获取
方法 | 描述 |
---|---|
getElementsByTagName() | 通过标签名获取元素节点数组 |
getElementsByName() | 通过元素的 Name 属性的值(IE 容错能力较强,会得到一个数组,其中包括 id 等于 name 值的) |
getElementById() | 通过元素 Id获取一个元素节点,唯一性 |
querySelector() | 通过类名或元素Id (JQuery方法) |
getElementsByClassName() | 通过类名获取元素节点数组 |
访问关系的获取
JS中的父子兄访问关系:
属性 | 描述 |
---|---|
节点.parentNode | 获取父节点 |
节点.nextElementSibling || 节点.nextSibling | 获取下一个兄弟节点 |
节点.previousElementSibling || 节点.previousSibling | 获取前一个兄弟节点 |
节点自己.parentNode.children[index] | 获得任意一个兄弟节点 |
节点.firstElementChild || 节点.firstChild | 第一个子元素节点 |
节点.lastElementChild || 节点.lastChild | 最后一个子元素节点 |
父节点.childNodes | 获取所有子节点(标准属性。返回的是指定元素的子节点的集合) |
父节点.children | 获取所有子节点(非标准属性。返回的是指定元素的子元素节点的集合) |
4、属性操作
属性/方法 | 描述 |
---|---|
元素节点.属性名 / 元素节点[属性名] | 获取节点的属性值 |
getAttribute() | 获取属性 |
setAttribute() | 设置属性 |
hasAttribute() | 判断属性 |
removeAttribute() | 移除属性 |
hasAttributes() | 是否有属性设置 |
nodeType属性
nodeType == 1 表示的是元素节点(标签)。
nodeType == 2 表示是属性节点。
nodeType == 3 是文本节点。
nodeType、nodeName、nodeValue
我们那下面这个标签来举例:
<div id="box" value="111">hello</div>
上面这个标签就包含了三种节点:
元素节点(标签)
属性节点
文本节点
获取这三个节点的方式如下:
var element = document.getElementById("box1"); //获取元素节点(标签)
var attribute = element.getAttributeNode("id"); //获取box1的属性节点
var txt = element.firstChild; //获取box1的文本节点
var value = element.getAttribute("id"); //获取id的属性值
console.log(element); // <div id="box" value="111">hello</div>
console.log(attribute); // id="box1"
console.log(txt); // "hello"
console.log(value); // box1
既然这三个都是节点,要想获取它们的nodeType、nodeName、nodeValue,代码如下:
var element = document.getElementById("box1"); //获取元素节点(标签)
var attribute = element.getAttributeNode("id"); //获取box1的属性节点
var txt = element.firstChild; //获取box1的文本节点
//获取nodeType
console.log(element.nodeType); //1
console.log(attribute.nodeType); //2
console.log(txt.nodeType); //3
console.log("--------------");
//获取nodeName
console.log(element.nodeName); //DIV
console.log(attribute.nodeName); //id
console.log(txt.nodeName); //#text
console.log("--------------");
//获取nodeValue
console.log(element.nodeValue); //null
console.log(attribute.nodeValue); //box1
console.log(txt.nodeValue); //生命壹号
innerHTML和innerText的区别
value:标签的value属性。
innerHTML:双闭合标签里面的内容(包含标签)。
innerText:双闭合标签里面的内容(不包含标签)。(老版本的火狐用textContent)
区别:
获取内容:innerHTML会获取到标签本身,而innerText则不会
修改内容:innerHTML会修改标签本身,而innerText则不会
documen.write 和 innerHTML 的区别
- document.write 只能重绘整个页面
- innerHTML 可以重绘页面的一部分
innerHTML 与 outerHTML 的区别?
DOM 元素的 innerHTML
, outerHTML
, innerText
, outerText
属性的区别也经常被面试官问到, 比如对于这样一个HTML元素:<div>content<br/></div>
。
innerHTML
:内部HTML,content<br/>
;outerHTML
:外部HTML,<div>content<br/></div>
;innerText
:内部文本,content
;outerText
:内部文本,content
;
上述四个属性不仅可以读取,还可以赋值。outerText
和 innerText
的区别在于 outerText
赋值时会把标签一起赋值掉,另外 xxText
赋值时HTML特殊字符会被转义。
jQuery的html()与innerHTML的区别?
jQuery的 .html()
会调用.innerHTML
来操作,但是会捕获异常,然后用 .empty()
, .append()
重新操作。 这是因为IE8中有些元素的 .innerHTML
是只读的。见:http://stackoverflow.com/questions/3563107/jquery-html-vs-innerhtml
Window 对象 与 document 对象
window
- Window 对象表示当前浏览器的窗口,是 JavaScript 的顶级对象。
- 我们创建的所有对象、函数、变量都是 Window 对象的成员。
- Window 对象的方法和属性是在全局范围内有效的。
document
- Document 对象是 HTML 文档的根节点与所有其他节点(元素节点,文本节点,属性节点, 注释节点)
- Document 对象使我们可以通过脚本对 HTML 页面中的所有元素进行访问
- Document 对象是 Window 对象的一部分,即 window.document
客户区坐标、页面坐标、屏幕坐标区别
客户区坐标:鼠标指针在可视区中的水平坐标(clientX)和垂直坐标(clientY)
页面坐标:鼠标指针在页面布局中的水平坐标(pageX)和垂直坐标(pageY)
屏幕坐标:设备物理屏幕的水平坐标(screenX)和垂直坐标(screenY)
mouseover/mouseout 与 mouseenter/mouseleave 的区别与联系
- mouseover/mouseout 是标准事件,所有浏览器都支持;mouseenter/mouseleave 是 IE5.5 引入的特有事件后来被 DOM3 标准采纳,现代标准浏览器也支持
- mouseover/mouseout 是冒泡事件;mouseenter/mouseleave不冒泡。需要为多个元素监听鼠标移入/出事件时,推荐 mouseover/mouseout 托管,提高性能
- 标准事件模型中 event.target 表示发生移入/出的元素,vent.relatedTarget对应移出/如元素;在老 IE 中 event.srcElement 表示发生移入/出的元素,event.toElement表示移出的目标元素,event.fromElement表示移入时的来源元素
focus/blur 与 focusin/focusout 的区别与联系
- focus/blur 不冒泡,focusin/focusout 冒泡
- focus/blur 兼容性好,focusin/focusout 在除 FireFox 外的浏览器下都保持良好兼容性,如需使用事件托管,可考虑在 FireFox 下使用事件捕获 elem.addEventListener(‘focus’, handler, true)
DOM事件
DOM 事件模型
先捕获,再到目标,再冒泡 。捕获是事件会从最外层开始发生,直到最具体的元素。冒泡是事件会从最内层的元素开始发生,一直向上传播,直到window对象。
DOM 事件流
DOM 标准采用捕获+冒泡。两种事件流都会触发 DOM 的所有对象,从 window 对象开始,也在 window 对象结束。
DOM 标准规定事件流包括三个阶段:事件捕获阶段;处于目标阶段;事件冒泡阶段。
描述 DOM 事件捕获的具体流程
从 window -> document -> html -> body -> … -> 目标元素
Event 对象常见应用
event对象 | 描述 |
---|---|
event.target | 触发事件的元素 |
event.currentTarget | 绑定事件的元素 |
event.preventDefault() | 阻止默认行为(event.cancelBubble()和 event.preventBubble 都已经废弃) |
event.stopPropagation() | 阻止在捕获阶段或冒泡阶段继续传播,而不是阻止冒泡 |
event.stopImmediatePropagation() | 阻止事件冒泡并且阻止相同事件的其他侦听器被调用。 |
事件的代理/委托
事件委托是指将事件绑定目标元素的到父元素上,利用冒泡机制触发该事件
优点:
- 可以减少事件注册,节省大量内存占用
- 可以将事件应用于动态添加的子元素上
但使用不当会造成事件在不应该触发时触发
ulEl.addEventListener(
"click",
function (event) {
var target = event.target || event.srcElement;
if (target && target.nodeName.toUpperCase() === "LI") {
console.log(target.innerHTML);
}
},
false
);
自定义事件
- Event
- CustomEvent
CustomEvent 不仅可以用来做自定义事件,还可以在后面跟一个 object 做参数
var evt = new Event("myEvent");
someDom.addEventListener("myEvent", function () {
//处理这个自定义事件
});
someDom.dispatchEvent(evt);
IE 的事件处理和 W3C 的事件处理有哪些区别?
绑定事件
- W3C: targetEl.addEventListener(‘click’, handler, false);
- IE: targetEl.attachEvent(‘onclick’, handler);
删除事件
- W3C: targetEl.removeEventListener(‘click’, handler, false);
- IE: targetEl.detachEvent(event, handler);
事件对象
- W3C: var e = arguments.callee.caller.arguments[0]
- IE: window.event
事件目标
- W3C: e.target
- IE: window.event.srcElement
阻止事件默认行为
- W3C: e.preventDefault()
- IE: window.event.returnValue = false’
阻止事件传播
- W3C: e.stopPropagation()
- IE: window.event.cancelBubble = true
参考:https://github.com/huyaocode/webKnowledge/blob/master/%E5%89%8D%E7%AB%AF%E5%9F%BA%E7%A1%80/JS/DOM.md
BOM 与 DOM 的关系
- javacsript 是通过访问 BOM 对象来访问、 控制、 修改浏览器
- BOM 的 window 包含了 document, 因此通过 window 对象的document 属性就可以访问、 检索、 修改文档内容与结构。
- document 对象又是 DOM 模型的根节点。
因此, BOM 包含了 DOM, 浏览器提供出来给予访问的是 BOM 对象, 从 BOM 对象再访 问到 DOM 对象, 从而 js 可以操作浏览器以及浏览器读取到的文档。