09 更多节点操作 创建元素归纳 注册事件 删除事件 DOM事件流的三个阶段 事件对象 更多事件 实战演练
更多节点操作(方法)
removeChild
removeChild() 方法指定元素的某个指定的子节点。
以 Node 对象返回被删除的节点,如果节点不存在则返回 null。
语法
节点.removeChild(子节点)
cloneNode
cloneNode(deep ) 方法创建节点的拷贝,并返回该副本。
- node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
- node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
例子
浅拷贝
<ul>
<li>1111</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
var lili = ul.children[0].cloneNode();
ul.appendChild(lili);
</script>
结果
<ul>
<li>1111</li>
<li>2</li>
<li>3</li>
<li></li>
</ul>
深拷贝
<ul>
<li>1111</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
var lili = ul.children[0].cloneNode(true);
ul.appendChild(lili);
</script>
结果
<ul>
<li>1111</li>
<li>2</li>
<li>3</li>
<li>1111</li>
</ul>
创建元素归纳
document.write() 创建元素
如果页面文档流加载完毕,再调用这句话会导致页面重绘
例子
页面文档流未加载完毕
<button>点击</button>
<script>
document.write('<div>123</div>');
</script>
点击按钮“点击”前后
点击
页面文档流加载完毕
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.onclick = function() {
document.write('<div>123</div>');
}
</script>
点击按钮“点击”前
点击
点击按钮“点击”后,结果
innerHTML 创建元素
innerHTML 是将内容写入某个DOM节点,不会导致页面全部重绘
且innerHTML 创建元素创建多个元素效率更高(不使用拼接字符串,用数组添加后用join一次性凭拼接),结构稍微复杂
例子
function fn() {
var d1 = +new Date();
var array = [];
for (var i = 0; i < 1000; i++) {
array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
}
document.body.innerHTML = array.join('');
var d2 = +new Date();
console.log(d2 - d1);
}
document.createElement() 创建元素
创建多个元素效率稍低,但是结构更为清晰
例子
function fn() {
var d1 = +new Date();
for (var i = 0; i < 1000; i++) {
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '2px';
div.style.border = '1px solid red';
document.body.appendChild(div);
}
var d2 = +new Date();
console.log(d2 - d1);
}
注册事件
传统方式注册事件
例子
var btns = document.querySelectorAll('button');
btns[0].onclick = function() {
alert('hi1');
}
事件侦听注册事件
例子
(1) 里面的事件类型是字符串 必定加引号 而且不带on
(2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert('hi2');
})
btns[1].addEventListener('click', function() {
alert('hi3');
})
btns[1].addEventListener('click', fn);//函数不需要加小括号
attachEvent
ie9以前的版本支持
btns[2].attachEvent('onclick', function() {
alert('hi4');
})
btns[2].attachEvent('onclick', fn);//函数不需要加小括号
删除事件
传统方式删除事件
例子
divs[0].onclick = null;
事件侦听删除事件
例子
divs[1].removeEventListener('click', fn);//函数不需要加小括号
detachEvent
例子
divs[2].detachEvent('onclick', fn1);
DOM事件流三个阶段
事件流描述的事从页面中接收事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
-
JS 代码中只能执行捕获或者冒泡其中的一个阶段。
-
onclick 和 attachEvent(ie) 只能得到冒泡阶段。
-
捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段 document -> html -> body -> father -> son
-
冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段 son -> father ->body -> html -> document
例子
addEventListener 第三个参数是 true
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');
}, true);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, true);
</script>
addEventListener 第三个参数是 false
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, false);
document.addEventListener('click', function() {
alert('document');
})
</script>
事件对象
含义
div.onclick = function(event ) {
console.log(event);
}
- event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看
- 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
- 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
- 这个事件对象我们可以自己命名 比如 event 、 evt、 e
- 事件对象也有兼容性问题 (ie678不兼容) 通过 window.event 兼容性的写法 e = e || window.event;
常见的属性和方法
e.target
-
e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素)
区别 : e.target 点击了那个元素,就返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁以下就是一个例子
ul.addEventListener('click', function(e) { // 我们给ul 绑定了事件 那么this 就指向ul console.log(this); console.log(e.currentTarget); // e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li console.log(e.target); })
由于这个东西也有兼容性问题,所以就有以下的兼容性写法
div.onclick = function(e) { e = e || window.event; var target = e.target || e.srcElement; console.log(target); }
-
跟 this 有个非常相似的属性 currentTarget ( ie678不兼容)(了解)
e.type
返回事件类型
例子
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
function fn(e) {
console.log(e.type);
}
e.preventDefault()
阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
例子
a.onclick = function(e) {
e.preventDefault();
alert(11);
})
e.returnValue
阻止默认行为 低版本浏览器 ie678 兼容 returnValue 属性
例子
a.onclick = function(e) {
e.returnValue;
alert(11);
}
return false(非传统)
我们可以利用return false 也能阻止默认行为 没有兼容性问题 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
例子
a.onclick = function(e) {
return false;
alert(11);
}
e.stopPropagation()
阻止冒泡 dom 推荐的标准 stopPropagation()
e.cancelBubble(非传统)
阻止冒泡 非标准 cancel 取消 bubble 泡泡
e.cancelBubble = true;
client
鼠标事件 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');
page
鼠标事件 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');
screen
鼠标事件 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
console.log('---------------------');
更多事件
contextmenu
上下文菜单。 当用户右击元素时将显示上下文菜单
例子
禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
selectstart
selectstart 事件在用户开始一个新的选择时候触发。
例子
禁止选中文字
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
实战演练
要求
跟随鼠标的小仙灵
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>小仙灵跟随</title>
<style type="text/css">
.fairy{
position: absolute;
left: 0px;
top: 0px;
}
body{
position: relative;
}
</style>
</head>
<body>
<div class="fairy">
小仙灵
</div>
<script type="text/javascript">
fairy=document.getElementsByClassName('fairy')[0];
document.onmousemove=function(e){
e = e || window.event;
var x=e.pageX;
var y=e.pageY;
fairy.style.left =x+'px';
fairy.style.top =y+'px';
}
</script>
</body>
</html>