RYF javascript笔记4


5. DOM

5.1 document对象

5.1.1 DOM的含义

文档对象模型(Document Object Model)。

5.1.2 document对象概述

document对象是文档的根节点,window.document属性就指向它。

document.childNodes属性返回该对象的所有子节点。

一般来说,document对象的第一个子节点是document.doctype,第二个子节点是document.documentElement。

5.1.3 document对象的属性

5.1.3.1 文档信息属性

title:文档的标题。
lastModified:文档文件的上一次修改时间。
referrer:文档的访问来源。
URL:文档的URL。

5.1.3.2 指向其他节点或对象的属性

doctype:文档类型节点。
documentElement:html元素节点。
head:head元素节点。
body:body元素节点。

5.1.3.3 指向特定元素集合的属性

document.forms :所有的form元素。
document.images:所有的img元素。
document.links:所有的a元素。
document.scripts:所有的script元素。
document.styleSheets:所有的link或者style元素。

5.1.3.4 implementation属性

该属性指向一个对象,提供浏览器支持的模块信息,它的hasFeature方法返回一个布尔值,表示是否支持某个模块。

document.implementation.hasFeature('MutationEvents','2.0') // true

5.1.4 document对象的方法

5.1.4.1 document.write()

document.write方法用于向页面写入内容。如果在页面已经渲染完成的情况下调用这个方法,会把原有的页面全部抹去,等于是在一个新建的页面上写入内容。
所以,一般document.write只能在页面渲染的过程中使用。

5.1.4.2 querySelector(),getElementById()

querySelector使用CSS选择器语法(还可以接受复杂的CSS选择器),
getElementById使用id属性(更高效)。
找不到返回null。

document.querySelector('#myElement')
document.getElementById('myElement')

5.1.4.2 querySelectorAll(),getElementsByTagName(),getElementsByClassName()

document.querySelectorAll('DIV:not(.ignore)');
document.getElementsByTagName('li')
document.getElementsByClassName('liClass')

5.1.4.3 getElementsByName()

用于选择拥有name属性的HTML元素,比如form、img、frame、embed和object。返回值是一组对象

var forms = document.getElementsByName("x");
forms[0].tagName // "FORM"

5.1.4.4 createElement(),createTextNode()

createElement方法用来生成元素节点,参数是元素节点的tagName属性
createTextNode方法用来生成文本节点。参数是要生成的文本节点的内容。

var elementNode = document.createElement('div');
var textNode = document.createTextNode('Hi');

5.1.4.5 hasFocus()

返回布尔值,表示当前文档之中是否有元素被激活或获得焦点。

focused = document.hasFocus();

5.2 Node对象

5.2.1 Node节点对象

DOM就是由Node组成的。Node分外:

  1. DOCUMENT_NODE 文档节点(window.document)、
  2. ELEMENT_NODE 元素节点
  3. ATTRIBUTE_NODE 属性节点(比如class="right")、
  4. TEXT_NODE 文本节点
  5. DOCUMENT_FRAGMENT_NODE 文档碎片节点
  6. DOCUMENT_TYPE_NODE 文档类型节点。

浏览器原生提供一个Node对象,上面所有类型的节点都是Node对象派生出来的,它们都继承了Node的属性和方法。

对于HTML文档,节点有以下类型:

5.2.1.1 Node对象的属性

1、nodeName属性和nodeType属性

nodeName节点的名称,nodeType节点的常数值。

类型 nodeName nodeType
ELEMENT_NODE 大写的HTML元素名 1
ATTRIBUTE_NODE 等同于Attr.name 2
TEXT_NODE #text 3

2、nodeValue属性

Text节点的nodeValue属性返回文本内容,其他的节点都返回null。

3、childNodes属性和children属性
childNodes返回所有子节点
children返回成员为HTML元素类型的子节点

4、指向其他节点的属性
firstChild:第一个子节点。
lastChild:最后一个子节点。
。。。

5.2.1.2 Node对象的方法

appendChild()
cloneNode()
compareDocumentPosition()
contains()
hasChildNodes()
insertBefore()
isEqualNode()
removeChild()
replaceChild()

5.2.2 Element对象

5.2.2.1 属性

每个HTML标签,都会转化成一个Element对象节点。
所有的Element节点的nodeType属性都是1,但是不同标签生成的节点是不一样的。

1、innerHTML属性,outerHTML属性,textContent属性,innerText属性,outerText属性

2、tagName属性

tagName属性返回该节点的HTML标签名,与nodeName属性(大写)相同。

document.querySelector('a').tagName // A

3、attributes属性

var atts = document.querySelector('a').attributes;

for(var i=0; i< atts.length; i++){
    console.log(atts[i].nodeName +'='+ atts[i].nodeValue);
}

5.2.2.2 className属性和classList属性

都返回HTML元素的class属性。

document.getElementById('myDiv').className // "one two three" document.getElementById('myDiv').classList // { // 0: "one" // 1: "two" // 2: "three" // length: 3 // }

classList对象有一系列方法。

add():增加一个class。
remove():移除一个class。
contains():检查该DOM元素是否包含某个class。
toggle():将某个class移入或移出该DOM元素。
item():返回列表中某个特定位置的class。
toString():将class的列表转为字符串。

比较className和classList写法的区别。

document.getElementById('foo').className += 'bold';
document.getElementById('foo').classList.add('bold');
document.getElementById('foo').classList.remove('bold');
document.getElementById('foo').className = 
  document.getElementById('foo').className.replace(/^bold$/, '');

5.2.2.3 html元素

html元素是网页的根元素,document.documentElement就指向它。

1、clientWidth属性,clientHeight属性

返回视口(用户当前能够看见的那部分,不包括滚动条)的大小。

他两基本上与window.innerWidth和window.innerHeight同义。只有一个区别,后者包括了滚动条。

(2)offsetWidth属性,offsetHeight属性

这两个属性返回html元素的宽度和高度,即网页的总宽度和总高度。

5.2.2.4 dataset属性

dataset属性用于操作HTML标签的data-*属性。

var id = document.getElementById("myDiv").dataset.id; document.getElementById("myDiv").dataset.id = "hello"; //赋值或添加 delete document.getElementById("myDiv").dataset.id //删除

注意:dataset属性使用骆驼拼写法表示属性名,这意味着data-hello-world会用dataset.helloWorld表示。而如果此时存在一个data-helloWorld属性,该属性将无法读取。

5.2.2.5 页面位置相关属性

1、offsetParent属性、offsetTop属性和offsetLeft属性
2、clientWidth属性和clientHeight属性
3、scrollHeight属性和scrollWidth属性
4、scrollTop属性和scrollLeft属性

5.2.2.6 style属性

style属性用来读写页面元素的行内CSS属性,详见 5.4

5.2.2.7 Element对象的方法

5.2.2.8 setAttribute(),removeAttribute()

document.getElementById('foo').setAttribute('role', 'button'); //
document.getElementById('foo').removeAttribute('role');

5.2.2.9 insertAdjacentHTML()

将一段字符串,作为HTML或XML对象,插入DOM。通常用这个方法添加新节点。

document.getElementById("box2").insertAdjacentHTML('beforebegin', '

This gets inserted.

');

第一个是插入的位置,第二个是插入的节点字符串。
关于插入的位置,可以取值:beforebegin、afterbegin、beforeend、afterend。

5.2.2.10 getBoundingClientRect方法

5.2.2.11 table元素

表格有一些特殊的DOM操作方法。

insertRow():在指定位置插入一个新行(tr)。
deleteRow():在指定位置删除一行(tr)。
insertCell():在指定位置插入一个单元格(td)。
deleteCell():在指定位置删除一个单元格(td)。

5.2.3 Text节点

文本对应Text节点,哪怕只有一个空格,也会形成文本节点。

5.3 DOM事件

5.3.1 概述

DOM定义了一些事件,并且允许开发者通过以下3个方式指定事件的回调函数。

1、HTML属性定义


2、Element对象的事件属性

div.onclick = function(event){
    console.log('触发事件');
};

3、addEventListener方法,removeEventListener方法

button.addEventListener('click', 
        function(){console.log('Hello world');}, 
        false);

其中第3个参数默认为false,表示回调函数只在冒泡阶段被触发。

5.3.2 事件的传播

5.3.2.1 传播的三个阶段

第一阶段:从文档的根元素(html元素)传导到目标元素,称为“捕获阶段”。
第二阶段:在目标元素上触发,称为“目标阶段”。
第三阶段:从目标元素传导回文档的根元素,称为“冒泡阶段”。

浏览器总是假定click事件的目标对象,是嵌套最深的那个元素。

5.3.2.2 事件的代理

由于事件有冒泡阶段,因此可以把子元素的回调函数定义在父元素上统一处理。这种方法叫做事件的代理。

var ul = document.querySelector('ul');
ul.addEventListener('click', function(event) {
   if (event.target.tagName.toLowerCase() === 'li') {
      // some code
   }
});

5.3.3 事件的类型

DOM支持多种事件。

5.3.3.1 用户界面事件

1、load事件,error事件
对资源的加载,成功了触发load事件,失败了触发error事件。
error事件不会冒泡。以防止引发父元素的error事件回调函数。

2、unload事件
卸载资源时触发。

3、beforeunload事件
在用户关闭网页时触发。它会自动跳出一个确认对话框,如果用户点击“取消”按钮,网页就不会关闭。

window.onbeforeunload = function() {
  if (textarea.value != textarea.defaultValue) {
    return '你确认要离开吗?';
  }
};

4、resize事件
改变浏览器窗口大小时触发。

5、abort事件
资源在加载成功前停止加载时触发该事件,主要发生在element、XMLHttpRequest、XMLHttpRequestUpload对象。

6、scroll事件
用户滚动窗口或某个元素时触发该事件,主要发生在element、document、window对象。

7、contextmenu事件
用户鼠标右击某个元素时触发,主要发生在element对象。

5.3.3.2 焦点事件

事件名称 涵义 事件的目标
blur 元素丧失焦点 Element(除了body和frameset元素) Document
focus 元素获得焦点 Element(除了body和frameset元素) Document
focusin 元素即将获得焦点,在focus之前触发 Element
focusout 元素即将丧失焦点,在blur之前触发 Element

5.3.3.3 表单事件

1、change事件
一些特定的表单元素(比如文本框和输入框)失去焦点、并且值发生变化时触发。

2、reset事件
表单重置(reset)时触发。

3、submit事件
表单提交(submit)时触发。

4、select事件
用户在文本框或输入框中选中文本时触发。

5.3.3.4 鼠标事件

1、click事件
它的定义是同一个位置完成一次mousedown和mouseup动作。它们的触发顺序是:mousedown,mouseup,最后click。

可以利用click事件进行CSRF(跨站请求伪造Cross-site request forgery)攻击。

2、dblclick事件
用户在element、document、window对象上用鼠标双击时触发。该事件会在mousedown、mouseup、click之后触发。

3、mousedown事件

4、mouseup事件
5、mouseenter事件
该事件与mouseover事件相似,区别在于mouseenter事件不会冒泡,而且当鼠标移出子元素的边界、当仍在父元素之中时,它不会在父元素上触发。

6、mouseleave事件
该事件与mouseout事件类似,区别在于mouseleave事件不会冒泡,而且要等到鼠标离开该元素本身和它的所有子元素时才触发。

7、mousemove事件
当鼠标持续移动时,该事件会连续触发。(性能)

8、mouseout事件

9、mouseover事件

10、wheel事件
用户滚动鼠标的滚轮时触发。

5.3.3.5 键盘事件

1、keydown事件

2、keypress事件
用户按下某个键时触发。如果用户一直按着,这个事件就持续触发。

3、keyup事件

//捕捉用户按下Ctrl+H键的代码
document.addEventListener('keydown', function(event) {
  if (event.ctrlKey && event.which === 72) {
    // open help widget
  }
});

5.3.3.6 document对象的特有事件

1、readystatechange
在readyState属性发生变化时触发。它的发生对象是document和XMLHttpRequest对象。

2、DOMContentLoaded
在网页解析完成时触发,此时各种外部资源(resource)还没有被完全下载。也就是说,这个事件比load的触发早得多。

5.3.3.7 拖拉事件

1、drag
drag事件在源对象被拖拉过程中触发。

2、dragstart,dragend
dragstart事件在用户开始用鼠标拖拉某个对象时触发,dragend事件在结束拖拉时触发。

3、dragenter,dragleave
dragenter事件在源对象拖拉进目标对象后,在目标对象上触发。dragleave事件在源对象离开目标对象后,在目标对象上触发。

4、dragover事件
dragover事件在源对象拖拉过另一个对象上方时,在后者上触发。

5、drop事件
当源对象被拖拉到目标对象上方,用户松开鼠标时,在目标对象上触发drop事件。

5.3.3.8 CSS事件

transitionEnd
animationstart,animationend,animationiteration

5.3.4 event对象

当事件发生以后,会生成一个事件对象event,在DOM中传递,也被作为参数传给回调函数。
IE8及以下版本,这个事件需要通过window对象的event属性读取,所以要获取这个对象,往往写成下面这样。

function myEventHandler(event) {
    var actualEvent = event || window.event;
    // handle actualEvent
}

5.3.4.1 event对象的属性

type:返回一个字符串,表示事件的名称。
target:返回一个Element节点,表示事件起源的那个节点。
keyCode:返回按键对应的ASCII码。
ctrlKey:返回一个布尔值,表示是否按下ctrl键。

5.3.4.2 click事件

click的event还包括:

pageX,pageY:点击位置相对于html元素的坐标,单位为CSS像素。
clientX,clientY:点击位置相对于视口(viewport)的坐标,单位为CSS像素。
screenX,screenY:点击位置相对于设备显示屏幕的坐标,单位为设备硬件的像素。

5.3.4.3 event对象的方法

5.3.5 自定义事件

用户还可以自定义事件,然后手动触发。

$('some-element').trigger('my-custom-event');

这是jQuery定义的trigger事件,它会层层向上冒泡。冒泡过程中,如果有一个元素定义了该事件的回调函数,该回调函数就会触发。

也可以使用浏览器原生方法创造自定义事件。

5.4 CSS操作

5.4.1 DOM元素的CSS操作

5.4.1.1 HTML元素的style属性

操CSS的最简单方法:通过DOM的getAttribute、setAttribute和removeAttribute方法。

div.setAttribute('style','background-color:red;');

5.4.1.2 style对象

DOM还提供style属性,指向一个对象(简称style对象),用来读写元素的行内CSS样式。

var divStyle = document.querySelector('div').style;
divStyle.backgroundColor = 'red';
divStyle.width = '100px';

1、style对象的属性名
它等于:去掉CSS规则名的横杠,横杠后的第一个字母大写。
如:background-color 改为 backgroundColor。
如果CSS规则名是js保留字,则改为“css”+规则名。如:float 改为 cssFloat。

注意,style对象的属性值都是字符串且包括单位。所以,divStyle.width不能设置为100,而要设置为'100px'。

2、style对象的cssText属性
用来读写或删除整个style属性。

divStyle.cssText = 'background-color:red;height:100px;width:100px;';

3、CSS模块的侦测
“CSS模块的侦测”是判断当前浏览器是否支持某个模块。

常用方法是,判断DOM元素的style对象的某个属性值是否为字符串。

typeof element.style.animationName === 'string';
typeof element.style.transform === 'string';

有时候,需要把不同浏览器的CSS规则前缀也考虑进去。

typeof document.getElementById("content").style['-webkit-animation'] === 'string'

4、style对象的方法
setPropertyValue(propertyName,value) // 写
getPropertyValue(propertyName) // 读
removeProperty(propertyName) // 删除

5、style对象的animation-play-state属性
用来控制暂停动画的播放。该属性需要加上浏览器前缀。

element.style.webkitAnimationPlayState = "paused";
element.style.webkitAnimationPlayState = "running";

5.4.1.3 CSS伪元素

CSS伪元素是通过CSS向DOM添加的元素,主要方法是通过“:before”和“:after”生成伪元素,然后用content属性指定伪元素的内容。

5.4.1.4 CSS事件

动画(animation)事件
过渡(transition)事件

5.4.2 样式表

5.4.2.1 获取样式表

document对象的styleSheets属性,包含一个类似数组的对象,里面是当前文档所有的link元素(指向样式表)和style元素。

var sheets = document.styleSheets;
var sheet = document.styleSheets[0];

5.4.2.2 样式表对象

样式表对象有许多属性和方法。

cssRules属性指向一个类似数组的对象,它的每个成员就是一条CSS规则,其cssText属性就是CSS规则的字符串。

var sheet = document.querySelector('#styleElement').sheet;
sheet.cssRules[0].cssText
// "body { background-color: red; margin: 20px; }"

insertRule和deleteRule方法 用于插入和删除CSS规则。
disabled属性 用于打开或关闭一张样式表。

5.4.2.3 添加样式表

添加内置样式表,就是在文档中添加style节点。
添加外部样式表,就是在文档中添加link节点。

var linkElm = document.createElement('link');
linkElm.setAttribute('type', 'text/css');
linkElm.setAttribute('href', 'reset-min.css');

document.head.appendChild(linkElm);

5.4.3 window.getComputedStyle方法

getComputedStyle方法返回一个HTML元素的最终样式信息的对象。

5.5 拖放操作

5.5.1 拖放操作

5.5.1.1 网页元素的draggable属性

draggable用于标识元素是否可以拖动。
在大多数浏览器中,a元素和img元素默认是可以拖放的。

5.5.1.2 事件

5.5.2 自定义网页元素(Custom Element)

通过JavaScript可以自定义网页元素。使用前,用document对象的registerElement方法登记该元素。

5.6 Mutation Observer

Mutation Observer(变动观察器)是监视DOM变动的接口。当DOM对象树发生任何变动的时候,Mutation Observer会得到通知。

它与事件有一个本质不同:事件是同步触发;Mutation Observer则是异步触发。

你可能感兴趣的:(RYF javascript笔记4)