# JavaScript DOM 重点核心

# DOM 操作 (增删改查)

# 创建

  1. document.write
  2. innerHTML
  3. createElement

#

  1. appendChild
  2. insertBefore

#

  1. removeChild

#

  1. 修改元素属性 : src, href, title 等
  2. 修改普通元素内容 : innerHTML, innerText
  3. 修改表单元素 : value, type, disabled 等
  4. 修改元素样式 : style, className

#

  1. DOM 提供的 API 方法 : getElementById, getElementsByTagName, 古老用法不太推荐
  2. H5 提供的新方法 : querySelector, querySelectAll (提倡)
  3. 利用节点操作获取元素:父 (parentNode), 子 (childNode), 兄 (previousElementSibling, nextElementSibling) 提倡

# 注册事件

给元素添加事件,成为注册事件或者绑定事件

注册方式有两种方式 : 传统方式和方法监听注册方式

# 传统注册方式

  • 利用 on 开头的事件 onclick
  • <button onclick=“alert("hi~")"></button>
  • btn.onclick = function() {}
  • 特点:注册事件的唯一性
  • 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
1
2
3
4
btns = document.querySelectorAll('button');
btns[0].onclick = function () {
alert("hi~~~");
}

# 方法监听注册方式

eventTarget.addEventListener(type, listener[, useCapture])

此方法将指定的监听器注册到 eventTarget (目标对象) 上,当该对象触发指定的事件时,就会执行事件处理函数

该方法接收三个参数 :

  • type : 事件类型字符串,如 click , mouseover , 注意这里不要带 on
  • listener : 事件处理函数,事件方式时,会调用该监听函数
  • useCapture : 可选参数,是一个布尔值,默认是 false , 学完 DOM 事件流后,就能进一步了解该参数了
1
2
3
4
5
6
7
btns[1].addEventListener('click', function () {
alert("hi~~~");
});

btns[1].addEventListener('click', function () {
alert("no hi~~~");
})

eventTarget.attachEvent(eventNameWithOn, callback)

此方法将指定的监听器注册到 eventTarget (目标对象) 上,当该对象触发指定的事件时,指定的回调函数就会被执行

该方法接收两个参数 :

  • eventNameWithOn : 事件类型字符串,比如 onclikc , onmouseover , 这里要带 on
  • callback : 事件处理函数,当目标触发事件时回调函数被调用
1
2
3
btns[2].attachEvent('onclick', function () {
alert("hi~~~");
})

# 解除事件

传统方式 : eventTarget.onclick = null;

1

方法监听方式 : eventTarget.removeEventListener (type, listener)

1
2
3
4
5
6
btns[1].addEventListener('click', fn);

function fn() {
alert("hi~~~~");
btns[1].removeEventListener('click', fn);
}

eventTarget.dettachEvent(eventNameWithOn, callback)

1
2
3
4
5
6
btns[2].attachEvent('onclick', fn1);

function fn1() {
alert("hello");
btns[2].dettachEvent('onclick', fn1);
}

# DOM 事件流

事件流描述的是从页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流

DOM事件等级以及事件冒泡、捕获_南郭菌!的博客-CSDN博客

# 捕获阶段

事件向下走进元素

1
2
3
4
5
6
7
8
9
10
11
son.addEventListener('click', function () {
alert('son');
}, true);

father.addEventListener('click', function () {
alert('father');
}, true);

box.addEventListener('click', function () {
alert('box');
}, true);

捕获阶段 : 由上至下传播

# 冒泡阶段

事件从元素上开始冒泡

1
2
3
4
5
6
7
8
9
10
11
son.addEventListener('click', function () {
alert('son');
}, false);

father.addEventListener('click', function () {
alert('father');
}, false);

box.addEventListener('click', function () {
alert('box');
}, false);

冒泡阶段 : 自下而上

注意 :

  • JS 代码中只能执行捕获或者冒泡其中的一个阶段
  • onclickattachEvent 只能得到冒泡阶段
  • addEventListener(type, Listener[, useCapture]) 第三个参数如果是 true , 表示在实践中捕获阶段调用事件处理程序,如果是 false (不写默认就是 false), 表示在事件冒泡阶段调用事件处理程序
  • 实际开发中很少使用事件捕获,更多关注事件冒泡
  • 有些事件没有冒泡,比如 onblur , onmouseover , onmouseout , onmouseleave
  • 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件

# 事件对象

当注册事件被触发时,会创建一个事件对象,并且会自动传入事件处理函数,也就是 function (), 括号中可以指定该事件对象的名字[1]

1
2
3
box.onclick = function () {
console.log(event); //默认是event, 但是webstorm提示该符号已被弃用
}
1
2
3
box.onclick = function (e) {
console.log(e); //和上面输出的内容一样,
}
事件对象属性方法说明
e.target返回触发事件的对象 (标准)
e.srcElement返回触发事件的对象 (非标准,IE6~8 使用)
e.type返回事件的类型,比如 click mouseover 不带 on
e.cancelBubble该属性阻止冒泡 (非标准,IE6~8 使用)
e.returnValue该属性阻止默认事件 (默认行为,非标准,IE6~8 使用)
e.preventDefault()该方法阻止默认事件 (默认行为,标准,比如不让链接跳转)
e.stopPropagation()阻止冒泡 (标准)
  • e.target

    1
    2
    3
    box.onclick = function (e) {
    console.log(e.target);
    }
  • e.type

    1
    2
    3
    box.onclick = function (e) {
    console.log(e.type);
    }
  • e.cancelBubble

    1
    2
    3
    4
    father.addEventListener('click', function (e) {
    alert('father');
    e.cancelBubble = true;
    }, false);
  • e.returnValue

    1
    2
    3
    a.onclick = function (e) {
    e.returnValue = false;
    }
  • e.preventDefault

    1
    2
    3
    a.onclick = function (e) {
    e.preventDefault();
    }
  • e.stopPropagation

    1
    2
    3
    4
    son.addEventListener('click', function (e) {
    alert('son');
    e.stopPropagation();
    }, false);

# 事件委托 (代理,委派)

不是给每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点

1
2
3
4
5
6
7
8
9
10
11
12
13
var ul = document.querySelector('ul');

ul.addEventListener('mouseover', function (e) {
if (e.target !== ul) {
e.target.style.backgroundColor = 'red';
e.target.style.color = 'white';
}
});

ul.addEventListener('mouseout', e => {
e.target.style.backgroundColor = '';
e.target.style.color = '';
});

# 常用的鼠标事件

# contextmenu

实现禁止鼠标右键效果

1
2
3
document.addEventListener('contextmenu', e => {
e.preventDefault();
});

# selectstart

实现禁止文字复制效果

1
2
3
document.addEventListener('selectstart', e => {
e.preventDefault();
});

# clientX && clientY

client 鼠标在可视区的 x 和 y 坐标

1
2
3
document.addEventListener('click', e => {
console.log(e.clientX + ',' + e.clientY);
});

# pageX && pageY

page 鼠标在整个页面的 x 和 y 坐标

1
2
3
document.addEventListener('click', e => {
console.log(e.pageX + ',' + e.pageY);
});

# screenX && screenY

screen 鼠标在电脑屏幕的 x 和 y 坐标

1
2
3
document.addEventListener('click', e => {
console.log(e.screenX + ',' + e.screenY);
});

# 常用的键盘事件

# onkeyup

当按键被松开时触发

1
2
3
document.onkeyup = function () {
console.log('我弹起来了');
}

# onkeydown

当按键被按下时触发

1
2
3
document.addEventListener('keydown', function () {
console.log('我按下来了');
});

# onkeypress

当按键被按下时触发 == 但是它不识别功能键,比如 ctrl , shift , 箭头

1
2
3
document.addEventListener('keypress', function () {
console.log('我被按下了press');
});

三个事件的执行顺序 : keydown ——> keypress ——> keyup

# key && keyCode

key 获取按下的按键,keyCode 获取按下的按键的 ASCⅡ 值 (已弃用)

1
2
3
4
document.addEventListener('keydown', function (e) {
console.log('我按下来了' + e.key);
console.log(e.keyCode);
});
  • keyup, keydown 的 key 属性不区分大小写,而 keypress 区分大小写

  1. 一直没搞懂这里的事件对象是怎么被创建的,又是怎么就能被事件处理函数直接用的 (因为没有参数的时候使用 event 也能使用) 直到看到后面用了一下箭头函数,通过箭头函数慢慢的回过神来,开始探究点击此处查看详情 ↩︎