Day40 事件、属性操作、节点操作
1. 事件
1.1 组织a标签跳转
<script>
window.onload=function(){
var a = document.getElementsByTagName('a')[0];
a.onclick=function(){
// xxxxxxxxxxxx
return true;
}
}
</script>
</head>
<body>
<a href="http://www.baidu.com" >百度</a>
</body>
1.2 鼠标事件
1.2.1 移入移出
onmouseover鼠标移入事件:在鼠标指针移动到元素上时触发。
onmouseout 鼠标移出事件:在鼠标指针移出元素后触发
onmouseenter鼠标进入事件:在鼠标指针进入到元素上时触发。
onmouseleave 鼠标离开事件:在鼠标指针离开元素后触发
var sup = $("#sup")[0];
var sub = $("#sub")[0];
// 会出现冒泡,由子触发父,事件源是子
// sup.onmouseover = mouseover;
// sub.onmouseover = mouseover;
// 不会出现冒泡,不能由子触发父,事件源还是父
sup.onmouseenter = mouseover;
sub.onmouseenter = mouseover;
function mouseover(e) {
console.log("我是谁 : " + this.id + " , 事件源是谁 : " + e.target.id);
}
1.2.2 获得焦点/失去焦点
onfocus获取焦点事件:在鼠标光标获取输入框焦点时触发
onblur失去焦点事件:在鼠标光标失去焦点时触发。
var inp = $("#inp")[0];
inp.onfocus=function(){
console.log("准备输入");
}
inp.onblur=function(){
console.log("输入完成");
if(this.value == ''){
alert("不能为空")
}
}
1.2.3 单击/双击
onclick单击事件:在鼠标指针单击时触发
ondblclick双击事件:在鼠标光标双击时触发。
var p = $('#p')[0];
p.onclick = function(){
console.log("点击了")
}
p.ondblclick=function(){
console.log('双击了')
}
1.3 键盘事件
onkeydown:键盘按下
onkeyup:键盘抬起
inp.onkeydown=function(e){
console.log("按下 : "+e.keyCode+" : "+e.key);
}
inp.onkeyup=function(e){
console.log("松开 : "+e.keyCode+" : "+e.key);
}
window.onscroll = function(){
console.log('------');
}
1.4 浏览器事件
onload:浏览器加载完成执行
onscroll:滚动浏览器滚动条时触发
window.onload = function () {}
2. 属性
2.1 元素自定义属性
标签除了自带属性之外,还可以根据我们自己的需求,去自定义属性,属性名自定义
<div id="" class="" xxx=""></div>
2.2 设置方式
setAttribute : DOM.setAttribute(“属性”,”值”); 为元素添加属性,可以自定义属性
getAttribute : DOM.getAttribute(“属性”) ; 获取元素的某个属性值,可以获取自定义的属性的值
removeAttribute : DOM.removeAttribute(“属性”); 删除元素的某个属性
setProperty : DOM.style.setProperty(“属性”,”值”) 设置css样式
cssText : DOM.style.cssText = “属性:值;属性:值;…”; 设置css样式
DOM.style.xxx = xxx; 设置css样式
DOM.属性=’值’ 设置标签已有的属性值,不可以自定义属性
<script>
var btn = document.getElementById("btn");
var dv = document.getElementById("box1");
btn.onclick=function(){
// 1 对象.style
dv.style.backgroundColor="pink";
// 2 对象.className
dv.className='box2';
// 3 对象.setAttribute
dv.setAttribute('style','background-color:yellow;');
// 4 对象.style.setProperty
dv.style.setProperty('background-color','green');
// 5 对象.style.cssText
dv.style.cssText = "background-color:pink;width:200px;";
}
</script>
3. 节点
3.1 是什么
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
整个文档是一个文档节点 document
每个 HTML 元素是元素节点
HTML 元素内的文本是文本节点
每个 HTML 属性是属性节点
注释是注释节点
3.2 nodeType
<body>
<div id='dv' class="dv1">我是div元素<span>11</span> </div>
</body>
<script>
// nodeType : 1 元素,2 属性, 3 文本 , 8 注释 , 9 文档
// 9
console.log(document.nodeType);
var dv1 = document.getElementById("dv");
// 1
console.log(dv1.nodeType);
// 获取属性节点
var classAttr = dv1.getAttributeNode("class");
// 2
console.log(classAttr.nodeType);
// 获取第一个子节点(包含文本节点)
var textNode = dv1.firstChild;
console.log(textNode);
// 3
console.log(textNode.nodeType);
// 第一个子元素节点,就是第一个子标签
var fec = dv1.firstElementChild;
// 1
console.log(fec.nodeType);
</script>
3.3 nodeName
// nodeName : 文档 #document , 文本 #text , 元素 大写标签名, 属性 属性名
// #document
console.log(document.nodeName);
// DIV
console.log(dv1.nodeName);
// class
console.log(classAttr.nodeName);
// #text
console.log(textNode.nodeName);
// SPAN
console.log(fec.nodeName);
3.4 nodeValue
// nodeValue : 元素 是 undefined 或 null , 属性 属性值 , 文本 文本内容
// null
console.log(document.nodeValue);
// null
console.log(dv1.nodeValue);
// dv1
console.log(classAttr.nodeValue);
// 我是div元素
console.log(textNode.nodeValue);
// null
console.log(fec.nodeValue);
3.5 常用方法
3.6 节点关系
节点之间的关系就是嵌套关系(父子关系)、并列关系(兄弟关系)。注意区分节点与元素节点之间的区别。
父节点–parentNode
父元素节点–parentElement
子节点–childNodes:标签节点、文本节点、注释节点 得到的是伪数组
子元素节点–children :标签节点
第一个子节点–firstChild:文本
第一个子元素节点–firstElementChild:第一个标签
最后一个子节点–lastChild:文本
最后一个子元素节点–lastElementChild: 最后一个标签
上一个子节点–previousSibling:文本
上一个子元素节点–previousElementSibling: 上一个标签
下一个子节点 --nextSibling:文本
下一个子元素节点–nextElementSibling: 下一个标签
总结:firstChild、lastChild、previousSibling、nextSibling获取到的都是文本,如果没有就是文本节点名称#text, firstElementChild、lastElementChild、previousElementSibling、nextElementSibling获取到的都是标签,如果没有就是空。
<body>
<ul id='list'>
文字
<li id="li1" name1='list2'>1111</li>
列表
<li id='li2'>2222</li>
<li id='li3'>333</li>
<!-- 没有设置id -->
<li>44444</li>
<li id='li5'>555</li>
<li id='li6'>666</li>
</ul>
</body>
<script>
// ul
var ulObj = document.getElementById("list");
// li2
var li2Obj = document.getElementById("li2");
// li6
var li6Obj = document.getElementById('li6');
// 父节点 -- parentNode
// body
console.log(ulObj.parentNode);
// ul
console.log(li2Obj.parentNode);
// 父元素 -- parentElement
// body
console.log(ulObj.parentElement);
// 所有子节点 : childNodes : 标签节点,文本节点,注释节点 ,返回伪数组
console.log(ulObj.childNodes);
// 所有子元素节点 : children : 标签节点
console.log(ulObj.children);
// 第一个子节点
console.log(ulObj.firstChild);
// 第一个子元素
console.log(ulObj.firstElementChild);
// 最后一个子节点
console.log(ulObj.lastChild);
// 最后一个子元素
console.log(ulObj.lastElementChild);
// 上一个节点 "列表 换行符"
console.log(li2Obj.previousSibling);
// 上一个元素节点 li1
console.log(li2Obj.previousElementSibling);
// 下一个节点 换行符
console.log(li2Obj.nextSibling);
// 下一个元素节点 li3
console.log(li2Obj.nextElementSibling);
// 换行符
console.log(li6Obj.nextSibling);
// null
console.log(li6Obj.nextElementSibling);
</script>
3.7 节点创建
3.7.1 第一种
<body>
<div id="dv1">
<span>span标签</span>
</div>
</body>
document.write("<p>段落</p>");
3.7.2 第二种
// 2 innerHTML : 在下级添加元素,会发生覆盖,不过可以使用 += 解决覆盖问题
var dv1 = document.getElementById("dv1");
dv1.innerHTML = "<p>段落</p>";
3.7.3 第三种
父元素.appendChild(子元素):给父元素末尾添加子元素
// 3 document.createElement();
// 创建h2标签对象
var h2Obj = document.createElement('h2');
// 创建文本节点对象
var txt = document.createTextNode("2号标题");
// 把文本节点设置到h2对象中
h2Obj.appendChild(txt);
// 把h2对象插入到dv1中
dv1.appendChild(h2Obj);
3.8 动态创建列表
1 按钮
2 盒子
按钮有点击事件,点击之后,在盒子中动态创建ul
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#btn {
width: 300px;
height: 100px;
}
#box {
width: 300px;
height: 300px;
border: 2px solid red;
margin-top: 30px;
}
ul {
list-style: none;
}
.li1 {
color: blue;
}
</style>
</head>
<body>
<button id='btn'>生成</button>
<div id='box'></div>
</body>
<script>
// 数据
var arr = ['代表不建议年轻人戴美瞳眼镜', '建议幼儿园小学放学延长至6点', '如何抗住怼脸拍', '妇女节', '当北体小哥哥接种新冠疫苗', '丁程鑫资助贫困大学生'];
// 对象初始化
var btn = document.getElementById('btn');
var box = document.getElementById('box');
// 事件
btn.onclick=function(){
// 1 创建ul标签
var ulObj = document.createElement('ul');
// 遍历数据
for (let index = 0; index < arr.length; index++) {
// 创建li标签
var liObj = document.createElement('li');
// 设置li文本内容
liObj.innerText = arr[index];
// 添加class属性
liObj.setAttribute('class','li'+(index+1));
// 绑定事件
liObj.onmouseover=fn1;
liObj.onmouseout=fn2;
// 添加到ul中
ulObj.appendChild(liObj);
}
// 把ul插入到box中
box.appendChild(ulObj);
// 移入
function fn1 (){
this.style.backgroundColor='red';
}
// 移出
function fn2 (){
this.style.backgroundColor='';
}
}
</script>
</html>
4. 事件进阶
4.1 事件三要素
事件源:是指那个元素引发的事件。比如当你点击cdsn图标的时候,会跳转到cdsn首页。那么这个cdsn图标就是事件源,再或者,可以这样理解, 当你对某个元素执行动作的时候,会触发一系列效果(动画,跳转…),那么这个元素就是事件源。
事件类型:例如,点击,鼠标划过,按下键盘,获得焦点。
事件驱动程序:事件驱动程序即执行的结果,例如,当你点击cdsn图标的时候,会跳转到cdsn首页。那么跳转到cdsn首页就是事件的处理结果。
执行事件的步骤:获取元素、绑定事件、书写事件驱动程序
4.2.1 事件绑定
DOM0会发生事件覆盖问题
btn.onclick = function(){
alert(1)
}
btn.onclick = function(){
alert(2)
}
以上程序 只会弹框 2 , 因为第二次绑定相同事件 会覆盖第一次绑定的事件
而DOM2 优化了事件绑定
使用 addEventListener,并且不会发生事件覆盖
btn.addEventListener(‘click’,function(){
alert(1)
});
btn.addEventListener(‘click’,function(){
alert(2)
});
以上DOM2绑定方式, 弹框1和弹框2 都会执行
4.2.2 事件绑定
DOM0解绑 btn.onclick = null;
DOM2解绑 btn.removeEventListener(‘click’,function);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id='btn1'>按钮1</button>
<button id='btn2'>按钮2</button>
</body>
<script>
var btn1 = document.getElementById('btn1');
// DOM0事件绑定
btn1.onclick = function(){
alert(1);
// DOM0取消绑定
this.onclick = null;
}
var btn2 = document.getElementById('btn2');
// DOM2事件绑定
btn2.addEventListener('click',btn2fn);
function btn2fn(){
alert(2);
// DOM2取消绑定
this.removeEventListener('click',btn2fn);
}
</script>
</html>
4.3 事件对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='dv1' style="width: 200px;height: 200px;background-color: red;margin: auto;">一个盒子</div>
</body>
<script>
var dv1 = document.getElementById('dv1');
dv1.onclick = function(event){
// 兼容性写法 获取事件对象
var event = event || window.event;
console.log(event);
// 事件源对象(谁触发的)
console.log(event.target);
// 事件类型
console.log(event.type);
// 鼠标在页面中的位置
console.log('X轴 : '+event.clientX+" , Y轴 : "+event.clientY);
console.log('X轴 : '+event.pageX+" , Y轴 : "+event.pageY);
}
</script>
</html>
4.4 事件源妙用
绑定事件后,如果还要新增元素,则新增元素不会拥有该事件监听
可以利用事件源,对父盒子绑定事件,然后通过事件源 找到真正触发该事件的元素,进行操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id='btn'>添加一个li</button>
<ul id="ul">
<li>11111</li>
<li>22222</li>
<li>33333</li>
</ul>
</body>
<script>
var ul = document.getElementById('ul');
var btn = document.getElementById('btn');
// 对ul绑定事件
// 移入
ul.onmouseover = function (event) {
var event = event || window.event;
var target = event.target;
// console.log(target.nodeName);
if (target.nodeName == 'UL') { return; }
target.style.color = "red";
}
// 移出
ul.onmouseout = function (event) {
var event = event || window.event;
var target = event.target;
if (target.nodeName == 'UL') { return; }
target.style.color = "";
}
var count = 1;
btn.onclick = function () {
var li = document.createElement('li');
li.innerText = '新增元素-' + count;
count++;
ul.appendChild(li);
}
// 通过测试 后添加的标签,会拥有事件
</script>
</html>
事件冒泡
如果父子标签绑定相同的事件监听,如果触发子元素的事件的时候,会从子到父依次触发绑定了该事件的元素事件
还有一种是捕获机制,相反,是从父到子依次触发
什么是冒泡事件
事件冒泡阶段:事件从事件目标(target)开始,往上冒泡直到页面的最上一级标签。
假设一个元素div,它有一个下级元素p。
<div>
<p>元素</p>
</div>
这两个元素都绑定了click事件,如果用户点击了p,它在div和p上都触发了click事件,那这两个事件处理程序哪个先执行呢?事件顺序是什么?
如何阻止冒泡(存在兼容性)
e.stopPropagation(); 谷歌和火狐支持,
window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持