前端基础知识复习(三)

知识点整理来源于网上。详细的介绍推荐直接看API文档。

DOM 功能

对元素的增查删改
① 查询某个元素
② 查询某个元素的祖先、兄弟以及后代元素
③ 获取、修改元素的属性
④ 获取、修改元素的内容
⑤ 创建、插入和删除元素

节点分类

根据标签确定
① 文档节点(Document):整个XML、HTML文档
② 元素节点(Element):每个XML、HTML元素
③ 属性节点(Attr):每个XML、HTML元素的属性
④ 文本节点(Text):每个XML、HTML元素内的文本
⑤ 注释节点(Comment):每个注释

注意:这里的Document节点为总称,具体可分为XMLDocument和HTMLDocument,同理Element也可分为XMLElement和HTMLElement。

节点层次

节点彼此都有等级关系:父节点、兄弟节点、子节点等等。


节点属性

  • innerHTML:以HTML代码格式获取或设置节点的内容,会以HTML的形式呈现。比如:node.innerHTML="<input type='button' value='按钮' />" 将会显示一个按钮。

    • document.getElementById('div').innerHTML="<input type='button' value='按钮' />";
  • innerText:获取或设置节点的文本内容,以文本字符串的形式获取或设置节点的内容。nodeName、nodeValue以及nodeType等。

  • nodeName:获取节点名称,只读属性

console.log( document.nodeName ); // => #document:文档节点
console.log( document.body.nodeName ); // => BODY:元素节点
console.log( document.getElementById('div').nodeName ); // => DIV:元素节点
console.log( document.getElementById('div').attributes.style.nodeName ); // => style:属性节点
```

  • nodeValue:获取或设置节点的值,文档节点、元素节点此属性返回null

console.log( document.nodeValue ); // => null:文档节点
console.log( document.body.nodeValue ); // => null:元素节点
console.log( document.getElementById('div').nodeValue ); // => null:元素节点
console.log( document.getElementById('div').attributes.style.nodeValue ); // => width:200px;height:100px;border:1px solid black;:style属性的值
document.getElementById('div').attributes.style.nodeValue = ' width:200px;height:200px'; // 设置style属性的值
```

  • nodeType:返回节点类型,只读属性
文档节点(Document)  9
元素节点(Element)    1
属性节点(Attr)   2
文本节点(Text)   3

测试

console.log( document.nodeType ); // => 9:文档节点
console.log( document.body.nodeType ); // => 1:元素节点
console.log( document.getElementById('div').nodeType ); // => 1:元素节点
console.log( document.getElementById('div').attributes.style.nodeType ); // => 2:属性节点

获取 HTML 元素节点方法

getElementById(id)

获取指定ID的元素
注意:
① HTML元素ID是区分大小写的。
② 若没有找到指定ID的元素,返回null。
③ 若一个父节点下面有多个相同ID元素时,默认选取第一个(而不是层级最高的)。


getElementsByName(name)

返回一个包含指定name名称的的元素数组
document.getElementsByName('Btn'); // 返回一个name为btn的元素数组

getElementsByTagName(elementName)

返回一个指定标签名称的的元素数组
document.getElementsByTagName('div'); // 返回一个标签为div的元素数组

DOM对象

  1. Document 对象:表示文档树的根节点,大部分属性和方法都是对元素进行操作。
  2. Element 对象:表示文档中的元素,可包含为元素节点、文本节点以及注释节点。
  3. Attr 属性对象:表示一个Element节点的属性。可获取、添加、修改指定的属性。
  4. Event 对象:表示事件发生时的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态等等。

直接查看API文档

HTML 事件

  1. 事件可表示为动作。以鼠标为例,移动、点击、悬停都是一种动作,也是事件。
  2. 事件类型(event type):表示事件的类型。如:MouseEvent(鼠标事件)、KeyboardEvent(键盘事件)。
  3. 事件名称(event name):表示事件的名称。如:click(单击)、dblclick(双击)。
  4. 事件目标(event target):表示与发生事件相关的目标对象。
    5.事件处理程序(event handler):指处理事件的函数,即发生事件时,需调用的函数。
  5. 事件对象(event object):事件发生时,表事件的状态,比如事件发生的目标、键盘按键的状态、鼠标的位置、鼠标按钮的状态等等。事件触发时,通过参数传递给事件处理程序。

HTML元素中的事件处理程序属性名称是以"on"为前缀,紧跟着事件的名称。如:onclick、onload。


事件类型

每一个事件都有归属的事件类型,不同的事件类型具有不同的信息。

  • UIEvent Types :用户界面事件类型;当用户与页面上的元素交互时触发
    • 包含事件:load、unload、abort、error、select、resize、scroll。
  • FocusEvent :焦点事件; 当元素获得或失去焦点时触发
    • 包含事件:blur、focus、focusin、focusout。
  • MouseEvent Types :鼠标事件类型;当鼠标在页面上执行操作时触发
    • 包含事件:click、dblclick、mousedown、mouseenter、mouseleave、mousemove、mouseout、mouseover、mouseup。
  • WheelEvent Types :滚轮事件类型;当鼠标滚轮时触发
    • 包含事件:wheel。
  • KeyboardEvent Types :键盘事件类型;当键盘在页面上执行操作时触发
    • 包含事件:keydown、keyup、keypress。
  • CompositionEvent Types:复合事件类型;当为IME输入字符时触发
    • 包含事件:compositionstart、compositionupdate、compositionend。

Event 事件对象(这部分比较重要

  • Event 对象表示事件发生时的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态等等

  • 获取方式:事件触发时的第一个参数 或者 事件触发时调用window.event对象。

document.getElementById('btn').addEventListener('click', function(e){
console.log(window.event==e); // => true :触发时两者是一样
  • 冒泡事件:当子元素触发某一事件时,父元素会触发相同时间(事件为允许冒泡)。
  • 阻止后续处理程序:通过addEventListener()方法可以给元素的同一事件注册多个处理程序,在某个事件中调用了stopImmediatePropagation() 方法后,后面已经注册的处理程序将不会执行。比如,某个元素在click事件上注册了3个函数,在第2个函数上调用了stopImmediatePropagation()方法,第3个函数不会执行。

具体的看文档

  • currentTarget 与 target 属性的区别
    • currentTarget :获取正在处理此事件的对象。
    • target :获取触发此事件的对象。

冒泡阶段时两者的区别: 假设body和Button元素都注册了click事件;当点击Button元素时,body的click事件也会触发,此时在body的click事件内,currentTarget指向body元素,target指向Button元素。

Event 事件的注册与注销(类比iOS中的事件)

  1. 注册事件:介绍通过元素的事件属性、addEventListener()以及attachEvent()方法进行事件的注册。
  2. 注销事件:介绍通过removeEventListener()、detachEvent()以及事件属性赋值为null来进行事件的注销。

注册事件

  1. 属性注册方式又可分为在HTML元素内的事件属性赋值和通过JS指定元素对象的事件属性
  2. 方法注册方式可通过addEventListener()或attachEvent()方法进行事件的注册。

在HTML元素内的事件属性赋值

说明:在HTML页面中,设置元素属性为一个函数。
语法:<button onlick="sayHello()">点击</button>
注意:事件属性是以"on"开头,后面跟着事件名称。如:onclick、onload。

function sayHello() {
    console.log('hello')
}
----
<button onclick="sayHello()">点击</button>

通过JS指定元素对象的事件属性

说明:通过JS获取元素的对象,设置其事件属性为一个事件处理程序。
语法:EventTarget.onEventName=function(e){};
注意:事件属性是以"on"开头,后面跟着事件名称。如:onclick、onload。
唯一性:属性注册具有唯一性;同一个事件,最后注册的处理程序将会覆盖前面注册的处理程序。

示例1:事件属性注册的演示
// 注册body的click事件
document.body.onclick = function (e) {
    alert(1);
};
示例2:事件属性注册的唯一性
document.body.onclick=function(e){
    console.log(1);
}
// 会覆盖前面注册的事件处理程序
document.body.onclick=function(e){
    console.log(2);
}
document.body.click(); // => 2 :只输出后面属性注册的

addEventListener()方法注册事件

说明:在JS中,window、document、HtmlElement等对象可以通过addEventListener()方法注册事件的处理程序。

语法:EventTarget.addEventListener(eventName, eventHandler, |useCapture )

参数:
①eventName {string} :所要注册的事件名称,不区分大小写。此名称不需要像注册事件属性那样前缀加上"on"。如注册鼠标点击事件,写为click。
②eventHandler {function | function Object} :函数或者函数对象。事件触发时所需要执行的函数;当使用函数对象多次注册同一事件时,只当注册一遍。
③useCapture {boolean} 可选 :是否处于捕获阶段,默认为false。

多次注册:addEventListener()方法能为同一个对象的同一事件注册多次。当发生此事件时,注册的处理事件程序将按照注册先后顺序执行。

注意:
①IE9之前的IE的不支持此方法,可使用attachEvent()代替。
②若使用相同的事件处理程序对象多次注册在同一个事件上,只算注册一次。

示例1:多次注册同一事件,按注册顺序执行,先输出1,再输出2

document.body.addEventListener('click',function(e){
     console.log('1');
});
         
document.body.addEventListener('click',function(e){
    console.log('2');
});
 
document.body.click(); // => 1,2

示例2:使用函数对象多次注册同一事件:只当注册一次
function sayHello(){
    console.log('hello');
}
 
document.body.addEventListener('click',sayHello);
// 使用处理程序多次注册同一事件,只当注册一次
document.body.addEventListener('click',sayHello);
 
document.body.click(); // => hello :只输出一遍

attachEvent()方法

IE相关,这里不扩展。

JQuery中的事件注册方式(工作中常用)

JQuery中的事件注册方式对多浏览器的差异性进行了解决:判断元素是否含有addEventListener()或者attachEvent()方法。

function add(element,type, eventHandle){
    if (element.addEventListener) {
        element.addEventListener(type, eventHandle, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, eventHandle);
    }
}

注销事件

可以注册元素的事件, 相应的可以也注销元素的事件。

JS中,可调用removeEventListener()[对应于addEventListener()] 和detachEvent()[对应于attachEvent()]来注销元素的某个事件指定的处理程序,也可以给事件属性赋值null来注销此事件的所有绑定。

removeEventListener(eventName, function Object)

说明:注销通过addEventListener()注册的事件处理程序。
语法:EventTarget.removeEventListener(eventName, eventHandlerObj)
参数:
①eventName {string} :所要注销的事件名称,不区分大小写。此名称不需要像注册事件属性那样前缀加上"on"。如注册鼠标点击事件,写为click。
②eventHandlerObj {function Object} :函数对象。传入一个函数体是没有效果的。

示例1:通过addEventListener()注销事件
function sayHello(e) {
    console.log('1');
}
 
// 注册body click事件
document.body.addEventListener('click', sayHello);
 
// 注销body click事件的sayHello函数
document.body.removeEventListener('click',sayHello);
 
document.body.click(); // 触发click事件,不输出任何结果
 

示例2:若第二个参数为函数体,将不会注销
function sayHello(e) {
    console.log('1');
}
 
// 注册body click事件
document.body.addEventListener('click', sayHello);
 
// 第二个参数为函数体,虽然跟sayHello函数的内容一样,但不会注销
document.body.removeEventListener('click', function(e) {
    console.log('1');
});
 
document.body.click(); // => 1 :输出结果为1,并没有注销成功

detachEvent(eventName, function Object)

说明:注销通过attachEvent()注册的事件处理程序。
语法:EventTarget.detachEvent(eventName, eventHandlerObj)
参数:
①eventName {string} :所要注销的事件名称,区分大小写。这里的名称跟事件属性一样,以"on"开头,后面跟着事件名称。如:onclick、onload。
②eventHandlerObj {function Object} ::函数对象。传入一个函数体是没有效果的。

取消事件

给对象的事件属性赋值为null,可取消此事件的所有注册过的处理事件程序。

注意是所有的。而前面介绍的是取消特定的处理函数。

Event事件流与事件委托(类比iOS中的事件响应过程)

事件流

事件流的三个阶段(和iOS非常相似)

2级DOM事件规范制定了事件流的三个阶段:捕获阶段、目标阶段和冒泡阶段:

捕获阶段(Capture Phase):事件从最外层的window对象到目标节点的父节点依次触发的阶段。(从外到内)

目标阶段(Target Phase):事件在目标节点上触发时的阶段。

冒泡阶段(Bubbing Phase):事件从目标节点的父节点到最外层的window对象依次触发的阶段。(从内到外)


addEventListener()注册事件流的阶段

元素对象通过addEventListener()注册事件时,此方法的的第三个参数可设置本次注册是捕获阶段还是冒泡阶段。

  • addEventListener()方法说明
    语法:EventTarget.addEventListener(eventName, eventHandler [, useCapture] )

参数:
①eventName {string} :所要注册的事件名称,不区分大小写。此名称不需要像注册事件属性那样在前缀加上"on"。如注册鼠标点击事件,写为click。
②eventHandler {function | function Object} :函数或者函数对象。事件触发时所需要执行的函数;当使用函数对象多次注册同一事件时,只当注册一遍。
③useCapture {boolean} 可选 :是否处于捕获阶段,默认为false。

|-true:当前注册的事件为捕获阶段。

|-false:当前注册的事件不为捕获阶段,为冒泡阶段。
  
实例:

function clickHandle(e){
    console.log("事件阶段:"+e.eventPhase+';target:'+e.target+';currentTarget:'+e.currentTarget)
}
 
window.addEventListener('click',clickHandle,false);
window.addEventListener('click',clickHandle,true);
document.addEventListener('click',clickHandle,false);
document.addEventListener('click',clickHandle,true);
document.documentElement.addEventListener('click',clickHandle,false);
document.documentElement.addEventListener('click',clickHandle,true);
document.body.addEventListener('click',clickHandle,false);
document.body.addEventListener('click',clickHandle,true);
document.getElementById('div').addEventListener('click',clickHandle,false);
document.getElementById('div').addEventListener('click',clickHandle,true);
document.getElementById('btn').addEventListener('click',clickHandle,false);
document.getElementById('btn').addEventListener('click',clickHandle,true);

阻止事件流的传播

Event 事件对象的stopPropagation()、stopImmediatePropagation()方法可阻止事件流的后续传播。
注:stopImmediatePropagation()方法除了阻止事件流传播还会阻止当前事件在此元素的后续事件处理程序。

在不同阶段阻止会立即阻止之后的操作,而不会影响之前的操作。

事件委托(Event Delegate)

简单来说事件委托就是父元素监听子元素的冒泡事件。

  • 详细解释:

    • HTML元素含有嵌套关系,并且事件流含有冒泡阶段。子元素的触发事件会冒泡到父元素的相同事件上。
    • 一般情况只需给子元素注册特定的事件处理程序即可,但当子元素过多或频繁的进行增减操作怎么办?
    • 比如一个ul包含了几十个li元素,对每个li元素进行单独的事件注册会影响性能。而现只要在父元素注册事件监听器,等待li事件触发后的冒泡阶段即可。
  • 实例

Div容器包含了多个li子元素,在Div容器注册事件委托。
HTML代码:
<div id="div">
    <ul id="ul" >
        <li data-key="北京">北京</li>
        <li data-key="上海">上海</li>
        <li data-key="杭州">杭州</li>
    </ul>
</div>
 

JS代码:
document.getElementById('div').addEventListener('click',function(e){
    var value=e.target.attributes['data-key'].value; // 获取目标阶段元素的'data-key'属性的值
    console.log(value);
});

JQuery的事件委托

在JQuery中,父元素可调用delegate()、on()作为事件委托使用。

delegate()

语法:$('父元素').delegate( selector [, eventType] [, eventData], handler )

参数:
①selector {string} :子元素的选择器、
②eventType {eventType} 可选 :触发的事件类型。如:click。
③eventData {object} 可选 :触发事件时event.data指向的值。
④handler {function} :事件注册的处理程序。

例子:

$('#div').delegate('li', 'click', function() {
    var v = $(this).data('key');
    console.log(v);
});

on()

说明:JQuery1.7版本开始时,推荐on()代替delegate()方法。
语法:$('元素').on( events [, selector ] [, data ], handler )

参数:
①events {string} :一个或多个事件名称。
②selector {string} 可选 :子元素选择器。若无此值,表示元素注册本身的事件。若含有此值,表示只有子元素的事件触发,才会触发注册的事件。
③data {object} 可选 :触发事件时的event.data指向的值。
④handler {function} :事件注册的处理程序。

$('#div').on('click','li',function(e) {
    var v = $(this).data('key');
    console.log(v);
});

Event模拟事件操作

具体的查看相关API

触发元素的事件可以直接调用事件方法(如:click()触发元素的click事件)。为何还要单独的模拟触发呢?

与直接触发相比,模拟事件包含以下特点:
①模拟特定场景:如触发click事件,可同时模拟是否按下Ctrl、Alt等按键。
②可触发自定义事件。

自定义事件

模拟事件支持模拟触发自定义事件。

例子:

<button id="a-btn">A按钮</button>
<button id="b-btn">B按钮</button>
JS:

// 按钮A
document.getElementById('a-btn').onclick=function(e){
    var customEvent=document.createEvent('CustomEvent'); // 1.创建一个自定义事件类型
    customEvent.initCustomEvent('build'); // 2.初始化一个build事件
    document.getElementById('b-btn').dispatchEvent(customEvent); // 3.派发(触发)
};
 
// 按钮B注册一个自定义事件
document.getElementById('b-btn').addEventListener('build',function(){
    console.log('b-btn build');
});

老版

通过document.createEvent()方法创建各事件类型对象。
①通过document.createEvent(eventType)方法创建一个event对象。
②调用event.initEvent()方法进行事件初始化。注意:不同的事件类型对象,其初始化的方法名称也不通;比如MouseEvent的为event.initMouseEvent()。
③调用元素对象的dispatchEvent(event对象)方法进行派发。

实例

模拟鼠标点击

HTML:
<button id="a-btn">A按钮</button>
<button id="b-btn">B按钮</button>
JS:
// 按钮A点击时,模拟触发按钮B的点击事件
document.getElementById('a-btn').onclick=function(e){
    var clickEvent=document.createEvent('MouseEvent'); // 1.创建一个鼠标事件类型
    clickEvent.initMouseEvent('click',false,false,window,0,0,0,0,0,false,false,false,false,0,null); // 2.初始化一个click事件
    document.getElementById('b-btn').dispatchEvent(clickEvent); // 3.派发(触发)
};
 
// 按钮B
document.getElementById('b-btn').onclick=function(e){
    console.log('b');
};

新版

通过各事件的构造函数创建事件类型对象。
①通过各事件类型的构造函数创建一个event对象。
②调用元素对象的dispatchEvent(event对象)方法进行派发。

实例

  • 模拟鼠标点击:模拟鼠标点击,按钮A和B都注册了各自的点击事件,点击按钮A时,模拟触发按钮B的点击事件并且模拟alt按键按下。
HTML:

<button id="a-btn">A按钮</button>
<button id="b-btn">B按钮</button>
JS:
// 按钮A点击时,模拟触发按钮B的点击事件
document.getElementById('a-btn').onclick=function(e){
    var clickEvent=new MouseEvent('click',{
        altKey:true // 模拟alt键按下
    });
    document.getElementById('b-btn').dispatchEvent(clickEvent); // 派发
};
 
// 按钮B
document.getElementById('b-btn').onclick=function(e){
    console.log('按钮b点击事件触发;alt案件是否按下:'+e.altKey);
};
  • 自定义事件:模拟事件支持模拟触发自定义事件。
HTML:

<button id="a-btn">A按钮</button>
<button id="b-btn">B按钮</button>
JS:

// 按钮A
document.getElementById('a-btn').onclick=function(e){
    var customEvent = new CustomEvent('build');
    document.getElementById('b-btn').dispatchEvent(customEvent); // 派发
};
 
// 按钮B注册一个自定义事件
document.getElementById('b-btn').addEventListener('build',function(){
    console.log('b-btn build');
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容