当前位置: 首页 > news >正文

webAPI中的节点操作、高级事件

一、节点操作

1.删除节点

node.removeChild(); 方法从node节点中删除一个子节点,返回删除的节点

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>01删除节点</title>
</head>
<body><button id="btn">删除</button><ul id="ul"><li>光头强</li><li>熊大</li><li>熊二</li></ul><script>//1.获取元素var ul = document.getElementById('ul');var btn = document.getElementById('btn');//2.注册事件btn.onclick = function(){if(ul.children.length == 0){this.disabled = true; //按钮禁用} else {//node.removeChild(要删除的对象);//ul.children[下标]表示是第几个孩子ul.removeChild(ul.children[0]);}}</script>
</body>
</html>

2.删除留言案例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>02删除留言案例</title><style>*{margin: 0; padding: 0;}body{padding: 100px;}textarea{width: 200px;height: 100px;border: 1px solid red;resize: none;}ul {margin-top: 50px;}li{width: 300px;padding: 5px;background-color: pink;color: #fff;font-size: 14px;margin: 15px 0;}</style>
</head>
<body><textarea name="" id="text"></textarea><br/><button id="btn">发布</button><ul id="ul"></ul><script>//1.获取元素var btn = document.getElementById('btn');var text = btn.previousElementSibling.previousElementSibling;//上一个兄弟节点var ul = btn.nextElementSibling; //获取下一个兄弟节点//2.注册事件btn.onclick = function(){if(text.value == ''){alert('请输入内容');return false;} else {//2.1 创建元素var li = document.createElement('li');//2.2 给li里面添加内容li.innerHTML = text.value + "<a href='javaScript:void(0);'  class='rm'>删除</a>";//2.3 添加元素//ul.appendChild(li);ul.insertBefore(li,ul.children[0]); //添加ul前面的第一个位置//2.4 获取到所有的a标签对象var as = document.getElementsByClassName('rm');//2.5 遍历所有的a,并给他注册事件for(var i = 0; i < as.length; i++){as[i].onclick = function(){//删除当前点击的这个节点//this是a标签对象   this.parentNode表示当前点击的这个li的父亲ul.removeChild(this.parentNode);}}}}</script>
</body>
</html>

3.复制(克隆)节点

node.cloneNode(); 括号里面可以不写,默认值是false,表示是浅拷贝,只拷贝标签不拷贝内容

node.cloneNode(true); 表示深拷贝,会拷贝标签和里面的内容

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><ul id="ul"><li>111</li><li>222</li><li>333</li></ul><script>// 1.获取对象var ul = document.getElementById('ul');//2 - 1 node.cloneNode();括号为空或者里面的值是false,表示浅拷贝,只复制标签不只复制里面的内容var li1 = ul.children[0].cloneNode();//2 - 2 node.cloneNode(true);括号为true,表示深拷贝,复制标签并且会复制标签种的内容var li2 = ul.children[0].cloneNode(true);//3.添加到ul中ul.appendChild(li1);ul.appendChild(li2);</script>
</body>
</html>

案例——动态生成表格

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>table{width: 500px;margin: 100px auto;border-collapse: collapse;text-align: center;}td,th{border: 1px solid #333;}thead tr{height: 40px;background-color: #ccc;}</style>
</head>
<body><table><thead><tr><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></tr></thead><tbody id="tbody"></tbody></table><script>//准备table中要添加的数据var datas = [{name:'柯震东',subject:'JavaScript',score:100},{name:'房祖名',subject:'Java',score:90},{name:'蔡徐坤',subject:'Python',score:80}];//往tbody种创建行var tbody = document.getElementById('tbody');//有多少条数据,添加多少次for(var i = 0; i < datas.length; i++){//1.创建tr行var tr = document.createElement('tr');//2.创建td (td的创建熟练和datas中的属性的个数有关)for(var k in datas[i]){ //循环datas中的属性var td = document.createElement('td');//把对象里面的属性值data[i][k]给td//3.td中添加数据//console.log(k + '--->' + datas[i][k]);td.innerHTML = datas[i][k]; //给属性赋值//4.将td加入到trtr.appendChild(td); }//添加操作按钮var td = document.createElement('td');td.innerHTML = '<a href="javaScript:;" class="del">删除</a>'tr.appendChild(td);//5.再将tr加入到tbody里面去tbody.appendChild(tr);}//删除操作//1.获取到所有的删除按钮var as = document.getElementsByClassName('del');//2.循环遍历,注册事件for(var i = 0; i < as.length; i++){as[i].onclick = function(){tbody.removeChild(this.parentNode.parentNode);}}</script>
</body>
</html>

4.创建元素的三种方式

  • document.write();
  • element.innerHTML
  • document.createElement();

区别:

  • document.write(); 是直接将内容写入到也买你内容流,但是文档流执行完毕,则它会导致页面全部重绘
  • innerHTML 是将内容写入到某个DOM节点,不会导致整个页面重绘,创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
  • createElement() 创建多个元素效率低一点点,但是结构更清晰(推荐

**注意:**innerHTML效率要比createElement高

4.1 创建方式

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>05三种创建元素的方式</title>
</head>
<body><button id="btn">点击</button><p>abc</p><div id="inner"></div><div id="create"></div><script>var btn = document.getElementById('btn');//1.document.write(); 创建元素,因为会重绘整个页面,很多场合不太适用// btn.onclick = function(){//     document.write('<div>123<div>');// }//2.innerHTML创建元素var inner = document.getElementById('inner');// for(var i = 0; i <= 100; i++){//     inner.innerHTML += '<a href="#">百度</a>'// }var arr = [];for(var i = 0 ;i <= 100; i++){arr.push('<a href="#">百度</a>');}inner.innerHTML = arr.join('');//3.document.createElement()创建元素var create = document.getElementById('create');for(var i = 0; i <= 100; i++){var a = document.createElement('a');a.setAttribute('href','#');a.innerHTML = '百度'create.append(a);}</script>
</body>
</html>

4.2 效率对比

innerHTML字符串拼接方式—效率低

createElement效率一般

innerHTML数组方式–效率高

innerHTML拼接字符串效率最低

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>06效率测试-innerHTML字符串拼接</title>
</head>
<body><script>function fn(){var d1 = + new Date();var str = '';for(var i = 0; i < 1000; i++){document.body.innerHTML += '<div style="width:100px;height=2px;border:1px solid blue;"></div>'}var d2 = + new Date();console.log(d2 - d1);}fn();</script>
</body>
</html>

innerHTML拼接数组效率最高

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>07效率测试-innerHTML数组拼接</title>
</head>
<body><script>function fn(){var d1 = + new Date();var arr = [];for(var i = 0; i < 1000; i++){arr.push('<div style="width:100px;height=2px;border:1px solid blue;"></div>')}document.body.innerHTML = arr.join('');var d2 = + new Date();console.log(d2 - d1);}fn();</script>
</body>
</html>

createElement效率一般

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>06效率测试-innerHTML字符串拼接</title>
</head>
<body><script>function fn(){var d1 = + new Date();for(var i = 0; i < 1000; i++){//document.body.innerHTML += '<div style="width:100px;height=2px;border:1px solid blue;"></div>'var div = document.createElement('div');div.style.width = '100px';div.style.height = '2px';div.style.border = '1px solid blue'document.body.appendChild(div);}var d2 = + new Date();console.log(d2 - d1);}fn();</script>
</body>
</html>

5.DOM核心总结

5.1 节点API

对于javaScript来说,为了操作HTML,js就有了一套自己的DOM编程接口

  • 创建节点
    • document.write()
    • innerHTML
    • createElement
  • 增加(将节点添加到某个节点)
    • appendChild
    • insertBefore
  • 删除
    • removeChild
    • 修改内容:innerHTML,innerText
    • 修改表单元素:value、type、disabled等等
    • 修改元素样式:style、className
  • 查询
    • 主要查找dom的元素怒
    • DOM提供的API方法:document.getElementById(id)、document.getElementsByTagName、document.getElementsByClassName
    • H5提供了新方法:querySelector、querySelectorAll
    • 利用节点操作获取元素:父节点(parentNode)、子节点(children)、兄(previousElementSibling、nextElementSibling)

5.2 属性操作

自定义属性

  • setAttribute 设置dom的属性值
  • getAttribute 获取dom的属性值
  • removeAttribute 移除属性值

内置属性:对象.属性=值; 对象.属性 获取值

5.3 事件操作(重点)

二、高级事件

1.注册事件

注册事件有两种方式:

  • 传统方式
    • 利用on开头的事件,如:onclick
    • 特点:注册事件的唯一性。同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。
  • 监听注册方式
    • w3c标准推荐方式
    • addEventListener() 它是一个方法。
    • 特点:同一个元素同一个事件可以注册多个监听器,执行顺序按照注册顺序依次执行。

2.事件监听

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>09事件监听</title>
</head>
<body><button id="btn1">传统注册事件</button><button id="btn2">方法监听注册事件</button><script>//获取到按钮var btn1 = document.getElementById('btn1');var btn2 = document.getElementById('btn2');//1.传统注册事件btn1.onclick = function(){alert('this is btn1');}btn1.onclick = function(){alert('btn1  hahahahahaahahah');}//2.事件监听  addEvenetListener//   1)里面的事件类型是一个字符串,必须加引号而且不带on//   2)同一个元素,同一个事件可以添加多个监听btn2.addEventListener('click',function(){alert('this is btn2');});btn2.addEventListener('click',function(){alert('btn2~~~~~~~~~~~~');});//3.【了解】  attachEvent  ie9以前的版本支持// btn1.attachEven('onclick',function(){//     alert('1111111');// });</script>
</body>
</html>

3.删除事件(解绑事件)

removeEventListener 删除事件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>10删除事件</title><style>div{width: 100px;height: 100px;background-color: pink;}</style>
</head>
<body><div>1</div><div>2</div><div>3</div><script>//获取所有的divvar divs = document.querySelectorAll('div');// var divs = document.getElementsByTagName('div');//给第一个div注册事件divs[0].onclick = function(){alert(111111);//传统的方式删除事件divs[0].onclick = null;}//removeEventListener  删除事件divs[1].addEventListener('click',fn);function fn(){alert(2222222);//删除事件divs[1].removeEventListener('click',fn);}</script>
</body>
</html>

4.DOM事件流

html中的标签都是相互嵌套的,我们可以将元素想象成一个盒子装着另一个盒子,document就是最外面的大盒子

当你单击一个div的时候,同时你页单击了div的父元素,甚至是整个页面

那么是先执行父元素的单击事件,还是先执行里面的div单击事件?

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

事件发生的时候在元素节点直接按照特点的顺序传播,这个传播过程,我们就称之为DOM事件流

  • 事件冒泡:IE浏览器最早提出,事件开始时由最具体的元素接受,然后逐级向上传播到DOM最顶层节点过程
  • 事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐层向下传播到最具体的元素接受的过程。
当时这2大浏览器霸主谁也不服谁。
IE提出从目标元素开始,然后一层一层向外接受事件并响应,也就是冒泡型事件流。
网景提出从最外层开始,然后一层一层向内接受事件并响应,也就是事件捕获流最终,w3c采用折中的方式,先捕获再冒泡
现代浏览器都遵循了此标准,所以事件发生的时候,会经历三个阶段。
  • 1.捕获阶段
  • 2.当前目标阶段
  • 3.冒泡阶段
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>11.事件的三个阶段</title><style>#father{width: 300px;height: 300px;margin: 100px auto;background-color: pink;text-align: center;}#son{width: 200px;height: 200px;margin: 50px;background-color: purple;line-height: 200px;color: #fff;}</style>
</head>
<body><div id="father"><div id="son">son盒子</div></div><script>//dom事件流三个阶段://1.js代码中只能执行捕获或冒泡其中的一个阶段//2.onclick只能得到冒泡阶段//3.捕获阶段,如果addEvenetListner 第三个参数是true,那么则处于捕获阶段 document->html->body->father->son// var son = document.getElementById('son');// son.addEventListener('click',function(){//     alert('son');// },true)// var father = document.getElementById('father');// father.addEventListener('click',function(){//     alert('father');// },true)//4.冒泡阶段,如果addEvenetListner第三个参数是false 或者省略不写,则处于冒泡阶段var son = document.getElementById('son');son.addEventListener('click',function(){alert('son');},false)var father = document.getElementById('father');father.addEventListener('click',function(){alert('father');},false)document.addEventListener('click',function(){alert('document');})</script>
</body>
</html>

5.事件对象

5.1 什么是事件对象

事件发生后,跟事件相关的一系列信息数据的集合都放在这个对象里面,这个对象就是事件对象。

如:

  • 谁绑定了事件
  • 鼠标触发事件的话,会得到鼠标相关的信息,如:鼠标的位置
  • 键盘触发事件的话,会得到键盘相关的信息,如:按下了哪个键

5.2 事件对象使用

div.onclick = function(e){}

div.addEventListener(‘click’,function(event){
console.log(event);
});

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>12事件对象</title><style>div{width: 100px;height: 100px;background-color: pink;}</style>
</head>
<body><div>123</div><script>//事件对象var div = document.querySelector('div');// div.onclick = function(e){//     // console.log(e);//     // console.log(window.event);//     e = e || window.event;//     console.log(e);// }div.addEventListener('click',function(event){console.log(event);});//1.event:就是一个事件对象,写到我们侦听函数的小括号里,当作形参来看//2.事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数//3.事件对象是我们事件的一些列相关数据的集合,跟事件相关,比如事件点击里面就包含了鼠标的相关信息//  鼠标的坐标,比如是键盘事件里面会包含键盘事件信息,比如判断用户按下了哪个键//4.这个事件我们可以自己命名的,比如:event、evt、e//5.事件对象也有兼容性的问题,现在没有问题了,有兼容性问题(IE678版本)可以写成e = e || window.event; </script>
</body>
</html>

5.3 e.target和this的区别

  • this是使劲按绑定的元素(绑定这个事件处理函数的元素)
  • e.target是事件触发的元素

通常情况下target和this是一致的。

但有一种情况不同:那就是再事件冒泡的时候。this指向的是父元素,而target指向的是子元素

this指向父元素是因为:它绑定的事件的元素对象就是父元素

target他是触发事件的哪个具体元素对象

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>13事件对象e.target</title>
</head>
<body><button id="btn">按钮</button><ul id="ul"><li>abc</li><li>def</li></ul><script>//常见事件的属性和方法//1.e.target返回的是触发事件的对象(元素)  this返回的是绑定事件的对象(元素)//区别:e.target点击了哪个元素,就返回这个元素。  this那个元素绑定了这个点击事件,那么返回的就是绑定者var btn  = document.getElementById('btn');btn.addEventListener('click',function(e){console.log(e.target)console.log(this);});var ul = document.getElementById('ul');ul.addEventListener('click',function(e){//因为我们给ul绑定了事件,那么this就是指向ulconsole.log(this);//console.log(e.currentTarget);//e.target指向我们点击那个对象,谁触发了这个事件,那么e.target就是谁console.log(e.target);})</script>
</body>
</html>

6.阻止默认行为

html中一些标签由默认行为,例如:a标签被点击了,默认进行页面跳转

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>14事件阻止默认行为</title>
</head>
<body><div>123</div><a href="http://www.baidu.com">百度</a><form action="http://www.baidu.com"><input type="submit" value="提交"></form><script>//获取对象var div = document.querySelector('div');div.addEventListener('click',fn);div.addEventListener('mouseover',fn);div.addEventListener('mouseout',fn);function fn(e){console.log(e.type);}//2.阻止默认事件(行为),让超链接不跳转,或者是表单不提交var a = document.querySelector('a');// a.addEventListener('click',function(e){//     e.preventDefault(); //阻止默认  dom标准写法// })//3.传统注册方式a.onclick = function(e){//e.preventDefault();return false; //利用return false也能阻止默认行为}var form = document.querySelector('form');form.onsubmit = function(){return false;}</script>
</body>
</html>

7.阻止事件冒泡

//阻止冒泡:dom推荐的是e.stopPropagation();

e.cancelBubble = true; //cancle:取消 Bubble:气泡,泡沫。(非标准写法)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>15阻止事件冒泡</title><style>.father{width: 300px;height: 300px;margin: 100px auto;background-color: pink;text-align: center;}.son{width: 100px;height: 100px;line-height: 100px;margin: 100px;background-color: purple;color: #fff;}</style>
</head>
<body><div class="father"><div class="son">son儿子</div></div><script>//获取对象//阻止冒泡:dom推荐的是e.stopPropagation(); var son = document.querySelector('.son');var father = document.querySelector('.father');son.addEventListener('click',function(e){alert('son');e.stopPropagation(); //阻止冒泡(传播) stop:阻止  Propagation:传播},false);father.addEventListener('click',function(e){alert('father');//e.stopPropagation();e.cancelBubble = true;  //cancle:取消 Bubble:气泡,泡沫。(非标准写法)},false);document.addEventListener('click',function(){alert('document');})</script>
</body>
</html>

8.事件委托

事件冒泡本身的特性,会带来坏处,同时也会带来好处。

8.1 什么是事件委托

把事情委托给别人,代为处理

事件委托也称为事件代理,在jQuery里面称之为事件委派

大白话:不给子元素注册事件,给父元素注册事件,把处理代码在父元素的事件中执行。

8.2 应用案例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>16.事件委托.html</title>
</head>
<body><ul><li>我爱中国1</li><li>我爱中国2</li><li>我爱中国3</li><li>我爱中国4</li><li>我爱中国5</li></ul><script>//获取对象var ul = document.querySelector('ul');ul.addEventListener('click',function(e){console.log(e.target);e.target.style.backgroundColor = 'pink'});</script>
</body>
</html>

9.常见的鼠标事件

9.1 常见事件

鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获取鼠标焦点
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标按键弹起触发
onmousedown鼠标按键按下触发

9.2 不可分享

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div>我是一段小说文字</div><script>//  1.contextmenu :就是我们鼠标右键事件document.addEventListener('contextmenu',function(e){e.preventDefault();});// 2.进制选中文字 selectstartdocument.addEventListener('selectstart',function(e){e.preventDefault()})</script>
</body>
</html>

9.3 鼠标事件对象

event 事件对象是事件相关的一系列信息的集合

现阶段我们主要使用鼠标事件对MouseEvent 和 键盘事件对象 KeyboardEvent

鼠标事件对象说明
e.clientX返回鼠标相对于浏览器窗口可视区域的X坐标
e.clientY返回鼠标相对于浏览器窗口可视区域的Y坐标
e.pageXIE9+支持,返回鼠标相对于文档页面X坐标
e.pageYIE9+支持,返回鼠标相对于文档页面Y坐标
e.screenX鼠标相对于电脑屏幕的X坐标
e.screenY鼠标相对于电脑屏幕的Y坐标
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>18.鼠标在页面中的坐标</title><style>body{height: 3000px;}</style>
</head>
<body><script>//鼠标事件对象document.addEventListener('click',function(e){//1.client 鼠标在可视区的x和y坐标console.log('clientX---->' + e.clientX);console.log('clientY---->' + e.clientY);//2.page  鼠标在页面文档的x和y坐标console.log('pageX---->' + e.pageX);console.log('pageY---->' + e.pageY);//3.screen  鼠标在电脑屏幕的x和y坐标console.log('screenX---->' + e.screenX);console.log('screenY---->' + e.screenY);});</script>
</body>
</html>

http://www.mrgr.cn/news/53935.html

相关文章:

  • 【ArcGIS Pro实操第五期】全局及局部空间插值:GPI、LPI、IDW等
  • 每日新闻掌握【2024年10月22日 星期二】
  • 二叉树遍历(前序、中序、后续)
  • Code Review Item
  • 大数据学习-Clickhouse
  • Adobe的反击,传统大厂全面AI化,正面激战OpenAI!
  • 在 Spring MVC 应用程序中使用 WebMvcTest 注释有什么用处?
  • 学习eNSP后,有哪些具体的就业方向?
  • 「数学::快速幂」矩阵快速幂运算|快速斐波那契数列 / LeetCode 509(C++)
  • 双十一有啥好用的物品可以推荐购买?2024不可错过的必囤好物清单!
  • 填充与步幅
  • oracle10g运维:存数据前
  • 51单片机快速入门之 LCD1602 液晶显示屏2024/10/19
  • C++20中头文件source_location的使用
  • JAVA本地编译运行出现的找不到类名问题
  • IMX6UL的RGB的显示实验
  • pandas-使用技巧
  • 自动Autowired注入
  • “打造个性化留言板:从页面搭建到功能实现“
  • 代码随想录day4| 24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点 、面试题 02.07. 链表相交、 142.环形链表II、链表总结
  • OpenGL 自定义SurfaceView Texture C++预览Camera视频
  • 浮动练习(1)
  • Vue3学习:vite项目中图片不能显示,报错 require is not defined
  • 《计算机视觉》—— 表情识别
  • UML图画法(动态图):用例图(Use Case Diagram)
  • 高级语言源程序转换为可执行目标文件