Day3 DOM-节点操作

news/2024/4/24 14:30:26/文章来源:https://blog.csdn.net/2301_76534754/article/details/136487108
3.1 节点
  • 节点:标签、文本、注释、换行等,节点类型nodeType、节点名称nodeName、节点值nodeValue

    元素:标签

  • 节点层级:父节点、子节点、兄弟节点

    parentNode父节点的最大节点是document,再朝上查找就是null

    prentElement最大父元素是html,再朝上查找就是null

    <!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>father<span>son</span></div><script>let span=document.querySelector('span')console.log(span.parentNode)  //div下的东西console.log(span.parentNode.parentNode.parentNode.parentNode)  //nulllet li=document.querySelector('li')console.log(li)  //nullconsole.log(span.parentElement)  //div下的东西console.log(span.parentElement.parentElement.parentElement.parentElement)  //null</script>
    </body>
    </html>
  • 子节点---childNodes;子元素---children拿到伪数组,开发中常用

    firstChild---第一个子节点;firstElementChild---第一个子元素(ie9以上才支持)

    lastChild---最后一个子节点;lastElementChild---最后一个子元素(ie9以上才支持)

    nodeType的换行---3、注释---8、元素---1

  • 兄弟节点

    nextSibling---下一个兄弟节点;previousSibling---上一个兄弟节点

    nextElementChild---下一个兄弟元素;previousElementSibling---上一个兄弟元素

    <!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><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><script>let ul=document.querySelector('ul')let li_second=ul.children[1]  //ul的第二个子元素console.log(li_second.nextSibling)  //ul的第二个子元素的下一个兄弟节点console.log(li_second.nextElementSibling)  //ul的第二个子元素的下一个兄弟元素let li_fourth=ul.children[3]  //ul的第四个子元素console.log(li_fourth.previousSibling)  //ul的第4个子元素的上一个兄弟节点console.log(li_fourth.previousElementSibling)  //ul的第4个子元素的上一个兄弟元素</script>
    </body>
    ​
    </html>
  • 添加节点

    1. 创建元素节点---createElement('标签名')

    2. 添加元素节点---parentNode.appendChild(变量名)

    3. 添加新增元素的内容---变量名.innerText=' '

    给兄弟元素前面插入兄弟元素---insertBefore(加谁,加在谁前面)

  • 删除元素---removeChild(元素)

    remove():括号内不写元素,则删除了所有

  • 替换节点---replaceChild(新节点,旧节点)

  • 克隆节点---cloneNode() 只克隆自己的标签,里面的内容未被克隆

    cloneNode(true) 克隆自己以及自己的子孙后代和内容​

练习

<body><ul></ul><button>新增</button><script>let arr = ['赵龙', '卢兴愿', '吴鑫', '龚政', '钱民君']let ul = document.querySelector('ul')let btn_append=document.querySelector('button')// 将数组中元素添加到ul中for (let i = 0; i < arr.length; i++) {let li = document.createElement('li')ul.appendChild(li)li.innerText = arr[i]// 添加删除按钮let btn = document.createElement('button')li.appendChild(btn)btn.innerText = '删除'// 添加删除事件/*btn.onclick = function () {btn.parentNode.remove()}*/
​btn.onclick =removefunction remove(){this.parentNode.remove()}}
​btn_append.onclick=function(){let newValue=prompt('请输入新数据:')let li = document.createElement('li')ul.appendChild(li)li.innerText = newValue// 添加删除按钮let btn = document.createElement('button')li.appendChild(btn)btn.innerText = '删除'// 添加删除事件btn.onclick = function () {btn.parentNode.remove()}}
​</script>
​
</body>
​
<body>
<button>按钮</button><script>var btn=document.querySelector('button')for(var i=0;i<10;i++){// 鼠标点击后,for循环已经完成了,所以此时的i=10btn.onclick=function(){console.log(i)  //10}}</script>
</body>

案例

<!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></ul><button>添加</button><script>let ul = document.querySelector('ul')let btn = document.querySelector('button')let arr = ['曹鑫宇', '康硕涵', '龚政', '赵龙', '吴穹', '任杰', '钱民君', '盛庆奥', '张国庆', '蔡浩男', '章杰', '卢兴愿', '吴鑫']// 按钮添加点击事件btn.onclick = fn1function fn1() {if (arr.length == 0) {alert('添加完毕')btn.onclick = null} else {let li = document.createElement('li')ul.appendChild(li)li.innerText = arr[0]arr.shift()}// li变红let lis = document.querySelectorAll('li')for (let i = 0; i < lis.length; i++) {// li背景颜色点击事件lis[i].onclick = fn2}}function fn2() {let lis = document.querySelectorAll('li')for (let j = 0; j < lis.length; j++) {lis[j].style.backgroundColor = ''}this.style.backgroundColor = 'red'}</script> -->
​<!-- 方式2: --><!-- <ul></ul><button>添加</button><script>let ul = document.querySelector('ul')let btn = document.querySelector('button')let arr = ['曹鑫宇', '康硕涵', '龚政', '赵龙', '吴穹', '任杰', '钱民君', '盛庆奥', '张国庆', '蔡浩男', '章杰', '卢兴愿', '吴鑫']let num = 0btn.onclick = function () {if (num == arr.length) {alert('添加完毕')btn.onclick = null} else {let li = document.createElement('li')ul.appendChild(li)li.innerText = arr[num]num++}
​for (let j = 0; j < ul.children.length; j++) {ul.children[j].onclick = fun}}function fun() {for (let k = 0; k < ul.children.length; k++) {ul.children[k].style.backgroundColor = ''}this.style.backgroundColor = 'red'}</script> -->
​<!-- 方式3: --><ul></ul><button>添加</button><script>var arr = ['曹鑫宇', '康硕涵', '龚政', '赵龙', '吴穹', '任杰', '钱民君', '盛庆奥', '张国庆', '蔡浩男', '章杰', '卢兴愿', '吴鑫']let ul = document.querySelector('ul')let but = document.querySelector('button')let num = 0but.onclick = function () {if (num == arr.length) {alert('数据已经添加完了')but.onclick = null} else {let lili = document.createElement('li')ul.appendChild(lili)lili.innerText = arr[num]num++}}// 事件委托--- li委托给了父元素 ulul.onclick = function (e) {for (let j = 0; j < ul.children.length; j++) {ul.children[j].style.backgroundColor = ''}// e.target指向触发的事件对象if (e.target.tagName == 'LI') {e.target.style.backgroundColor = 'red'}}</script>
​
​
</body>
​
</html>

3.2 DOM事件流

DOM事件流分三个阶段:捕获 目标元素 冒泡

捕获阶段:document -> html -> body ->父元素 ->目标元素

冒泡阶段: 目标元素->父元素->body -> html -> document

onclick只能拿到冒泡阶段,不能拿到捕获阶段

<!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>.f{width: 400px;height: 400px;background-color: pink;}.s{width: 100px;height: 100px;background-color: skyblue;}</style>
</head>
​
<body><div class="f">father<div class="s">son</div></div><script>let f=document.querySelector('.f')let s=document.querySelector('.s')f.onclick=function(){alert('father')}// 触发s事件时,先弹出son再弹出fathers.onclick=function(){alert('son')}</script>
</body>
​
</html>
  • 注册事件方法

    • 传统事件:给元素重复注册一个事件时,只会执行最后一个(冒泡阶段)---onclick 、oninput 、onmousemove

      传统事件的删除方法---元素.事件类型=null

    • 事件监听(ie9以上):给元素重复注册一个事件时,都会执行(第三个布尔值为true为捕获阶段,false或者空则为冒泡阶段)--- 元素.addEventListerner('事件类型',function(){ })

      监听事件的删除方法---元素.removeEventListerner('事件类型',function(){ })

  • 事件流的特点

    传统事件只有冒泡阶段,没有捕获阶段

    事件监听:元素.addEventListerner('事件类型',事件处理函数,布尔值)

    布尔值省略或者为false,会触发冒泡阶段;布尔值为true时,会触发捕获阶段

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

    比如:

    1.事件对象的使用

    事件触发发生时就会产生事件对象,并且系统会以实参的形式传给事件处理函数

    所以,在事件处理函数中声明1个形参用来接收事件对象。

    2.事件对象的兼容性处理

    事件对象本身的获取存在兼容问题:

     <div>123</div><script>var div = document.querySelector('div');div.onclick = function(e) {// 事件对象e = e || window.event;console.log(e);}</script>

    3.e.target 和 this 的区别

    常情况下terget 和 this是一致的,
    但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行)
    这时候this指向的是父元素,因为它是绑定事件的元素对象,
    而target指向的是子元素,因为他是触发事件的那个具体元素对象。 
    <div>123</div><script>var div = document.querySelector('div');div.addEventListener('click', function(e) {// e.target 和 this指向的都是divconsole.log(e.target);console.log(this);
    ​});</script>

    事件冒泡下的e.target和this

    <ul><li>abc</li><li>abc</li><li>abc</li></ul><script>var ul = document.querySelector('ul');ul.addEventListener('click', function(e) {// 我们给ul 绑定了事件  那么this 就指向ul  console.log(this); // ul
    ​// e.target 触发了事件的对象 我们点击的是li e.target 指向的就是liconsole.log(e.target); // li});</script>

    阻止默认行为

    html中一些标签有默认行为,例如a标签被单击后,默认会进行页面跳转。

    e.preventDefault()----dom标准写法

    return false;-----没有兼容性问题

    e.returnValue = false;------有兼容性问题

     <a href="http://www.baidu.com">百度</a><script>// 2. 阻止默认行为 让链接不跳转 var a = document.querySelector('a');a.addEventListener('click', function(e) {e.preventDefault(); //  dom 标准写法});// 3. 传统的注册方式a.onclick = function(e) {// 普通浏览器 e.preventDefault();  方法e.preventDefault();// 低版本浏览器 ie678  returnValue  属性e.returnValue = false;// 我们可以利用return false 也能阻止默认行为 没有兼容性问题return false;}</script>

    阻止事件冒泡

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

    e.stopPropagation(); ----阻止冒泡

    window.event.cancelBubble = true;------了解

       
     <div class="father"><div class="son">son儿子</div></div><script>var son = document.querySelector('.son');// 给son注册单击事件son.addEventListener('click', function(e) {alert('son');e.stopPropagation(); // stop 停止  Propagation 传播window.event.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡}, false);
    ​var father = document.querySelector('.father');// 给father注册单击事件father.addEventListener('click', function() {alert('father');}, false);// 给document注册单击事件document.addEventListener('click', function() {alert('document');})</script>
    1. 谁绑定了这个事件。

    2. 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。

    3. 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。

    4. 标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。

    5. 在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。

    • this 是事件绑定的元素(绑定这个事件处理函数的元素) 。

    • e.target 是事件触发的元素。

  • 事件委托

    什么是事件委托

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

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

    事件委托的原理

    给父元素注册事件,利用事件冒泡,当子元素的事件触发,会冒泡到父元素,然后去控制相应的子元素。

    事件委托的作用

    • 我们只操作了一次 DOM ,提高了程序的性能。

    • 动态新创建的子元素,也拥有事件。

        
       <ul><li>今天是快乐的一天!</li><li>今天是快乐的一天!</li><li>今天是快乐的一天!</li><li>今天是快乐的一天!</li><li>今天是快乐的一天!</li></ul><script>// 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点var ul = document.querySelector('ul');ul.addEventListener('click', function(e) {// e.target 这个可以得到我们点击的对象e.target.style.backgroundColor = 'pink';})</script>

  • 获取鼠标在页面的坐标

    屏幕可视区域:e.clientX、e.clientY

    页面:e.pageX、e.pageY----会随着页面滑动坐标发生变化

    浏览器距离电脑屏幕:e.screenX、e.screenY

       
     <script>// 鼠标事件对象 MouseEventdocument.addEventListener('click', function(e) {// 1. client 鼠标在可视区的x和y坐标console.log(e.clientX);console.log(e.clientY);​// 2. page 鼠标在页面文档的x和y坐标console.log(e.pageX);console.log(e.pageY);​// 3. screen 鼠标在电脑屏幕的x和y坐标console.log(e.screenX);console.log(e.screenY);
    ​})</script>

案例

<!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>body {background-color: blueviolet;}
​.div {width: 100px;height: 100px;background-color: skyblue;position: absolute;top: 0;left: 0;}
​img {width: 100%;height: 100%;}
​.box {width: 300px;height: 300px;background-color: pink;margin-top: 300px;margin-left: 500px;}</style>
</head>
​
<body><div class="div"><img src="../images/fresh_goods_7.jpg" alt=""></div><div class="box"></div><script>// 鼠标按下(在图片区域按下)拖拽盒子才会移动 // 鼠标在中间盒子区域外松开后盒子停止移动// 鼠标在中间盒子区域松开 图片会展示在中间盒子内,然后图片回到原始位置
​// 有个盒子,获取元素,给元素添加事件var div = document.querySelector('.div')var img = document.querySelector('img')var box = document.querySelector('.box')div.onmousedown = function (e) {// 把鼠标点击的坐标赋给div的top和leftdiv.style.top = e.clientY + 'px'div.style.left = e.clientX + 'px'// 鼠标先在图片上按下后才能进行移动事件document.onmousemove = function (e) {div.style.top = e.clientY + 'px'div.style.left = e.clientX + 'px'}}// 添加鼠标抬起事件,让图片停止移动div.onmouseup = function (e) {// 清除鼠标在文档中的移动事件document.onmousemove = null// 通过div的第一个孩子img来获取图片的路径var imgSrc = this.children[0].src// 鼠标在y轴方向坐标300-500,图片才能完全在box里// 鼠标在x轴方向坐标500-700,图片才能完全在box里if (e.clientX > 500 && e.clientX < 800 && e.clientY > 300 && e.clientY < 600) {// 原本box里面没有img,所以box_img初始状态为nullvar box_img = box.querySelector('img')div.style.top = 0div.style.left = 0// 当box第一次获取到图片后,box_img=trueif (box_img) return// 创建imgvar img = document.createElement('img')img.src = imgSrcbox.appendChild(img)}}
​
​
​</script>
</body>
​
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_999111.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter学习9 - http 中 get/post 请求示例

1、配置 http pubspec.yaml dependencies:http: ^0.13.4flutter:sdk: flutterhttp 库最新插件版本查看&#xff1a;https://pub.dev/packages/http不一定要用最新版本 http&#xff0c;要使用项目所能支持的版本 .dart import package:http/http.dart as http;2、示例 &a…

VsCode中使用Anaconda中的python环境

1、今天在新的电脑上安装了VsCode和Anaconda&#xff0c;但是在VsCode却选择不了python的环境&#xff0c;期望结果是下面这样的 2、接着在网上百度&#xff0c;找到了方法&#xff0c;具体方法如下&#xff1a; 2.1需要先在Extensions中安装python 2.2再使用ctrlshiftP后使用…

分布式数据库 GaiaDB-X 金融应用实践

1 银行新一代核心系统建设背景及架构 在银行的 IT 建设历程中&#xff0c;尤其是中大行&#xff0c;大多都基于大型机和小型机来构建核心系统。随着银行业务的快速发展&#xff0c;这样的系统对业务的支持越来越举步维艰&#xff0c;主要体现在以下四个方面&#xff1a; 首先是…

日韩媒体宣传案例分析:CloudNEO 为您提供海外媒体宣传最佳途径

近年来&#xff0c;随着互联网的迅速发展和全球化的加速推进&#xff0c;海外市场对于企业的重要性日益凸显。尤其是在亚洲地区&#xff0c;日本和韩国作为亚洲最具活力和潜力的市场之一&#xff0c;成为众多企业争相开拓的目标。在这个过程中&#xff0c;媒体宣传不仅是企业推…

K8S实现零宕机实践

越来越多的大厂都在上云、上容器、上K8S编排&#xff0c;K8S和容器云确实帮助我们解决了很多问题。但是&#xff0c;带来方便的同时&#xff0c;也让我们的架构变得更复杂了&#xff0c;更难于依靠“老经验”来解决问题了。虽然我们不用再费力考虑一层的问题&#xff0c;怎么实…

链表习题-力扣oj (附加思路版)

LCR 140. 训练计划 IIhttps://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/ 给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号&#xff0c;请查找并返回倒数第 cnt 个训练项目编号。 思路&#xff1a;双指针&#xff0c;快指针先走cnt…

liteIDE 解决go root报错 go: cannot find GOROOT directory: c:\go

liteIDE环境配置 我使用的liteIDE为 x36 5.9.5版本 。在查看–>选项 中可以看到 LiteEnv&#xff0c;双击LiteEnv &#xff0c;在右侧选择对应系统的env文件&#xff0c;我的是win64系统&#xff0c;所以文件名为win64.env 再双击 win64.env &#xff0c;关闭当前窗口&…

Redis冲冲冲——redis数据类型及对应的数据结构

目录 引出redis数据类型及对应的数据结构Redis入门1.Redis是什么&#xff1f;2.Redis里面存Java对象 Redis进阶1.雪崩/ 击穿 / 穿透2.Redis高可用-主从哨兵3.持久化RDB和AOF4.Redis未授权访问漏洞5.Redis里面安装BloomFilte Redis的应用1.验证码2.Redis高并发抢购3.缓存预热用户…

HarmonyOS NEXT应用开发案例——自定义TabBar

介绍 本示例主要介绍了TabBar中间页面如何实现有一圈圆弧外轮廓以及TabBar页签被点击之后会改变图标显示&#xff0c;并有一小段动画效果。 效果图预览 使用说明&#xff1a; 依次点击tabBar页面&#xff0c;除了社区图标之外&#xff0c;其它图标往上移动一小段距离。 实现…

uniapp 手写 简易 时间轴 组件

一、案例如图 该案例设计条件&#xff1a; 左侧时间 和竖线、点、内容都是居中对其的&#xff0c;上下时间点中间要有一段距离 二、编写逻辑 1. 布局结构&#xff1a;一共三个元素&#xff0c;左侧是时间和黑点&#xff0c;中间是线条&#xff0c;右侧是内容 2. 样式难点&#…

换手机后日记不见了怎么恢复?换手机日记内容同步方法

曾经&#xff0c;我使用的是一款苹果手机&#xff0c;这部手机陪伴了我整整3年。随着时间的推移&#xff0c;手机内存不够用成为了我面临的一个大问题&#xff0c;因此我决定更换一部新手机——这次我选择了OPPO品牌。在更换手机的过程中&#xff0c;我利用手机搬家软件一键同步…

Flutter使用auto_updater实现windows/mac桌面应用版本升级功能

因为windows应用一般大家都是从网上下载的&#xff0c;后期版本肯定会更新&#xff0c;那用flutter开发windows应用&#xff0c;怎么实现应用内版本更新功能了&#xff1f;可以使用auto_updater库&#xff0c; 这个插件允许 Flutter 桌面 应用自动更新自己 (基于 sparkle 和 wi…

【三维重建】VastGaussian:用于大场景重建的大3D Gaussian(CVPR 2024)

题目&#xff1a;VastGaussian: Vast 3D Gaussians for Large Scene Reconstruction 来源&#xff1a;清华大学&#xff1b;华为诺亚&#xff1b;中国科学院 链接&#xff1a;https://vastgaussian.github.io/ 总结&#xff1a;VastGaussian&#xff1a;基于3D GS的分块优化重…

mysql数据库(下)

目录 约束 约束的概念和分类 1、约束的概念&#xff1a; 2、约束的分类 1、主键约束 2、默认约束 3、非空约束 4、唯一约束 5、外键约束 约束 约束的概念和分类 1、约束的概念&#xff1a; 约束时作用于表中列上的规则&#xff0c;用于限制加入表的数据约束的存在保证…

【网站项目】105校园车辆管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

SHARE 100M PRO:航测领域的多面手

在无人机航测领域&#xff0c;SHARE 100M PRO单镜头航测相机以其1.02亿像素的中画幅传感器和创新技术&#xff0c;正在重塑倾斜摄影的精度和效率。这款相机不仅在城市规划和土地管理中发挥着重要作用&#xff0c;还在环境监测、基础设施建设、农业管理等多个航测领域展现出其卓…

自编C++题目——几点了.easy ver

题目难度 入门 题目描述 一个老外用一口不流利的中文问你&#xff1a;“Xian zai ji dian le?”你看了一眼表&#xff0c;知道了现在是&#xff0c;你准备用这样的形式写在纸上&#xff1a; Now is m past/to h. 如果你看不懂&#xff0c;举个例子&#xff1a; 当h10&#…

treeview控件的应用

1.分类 treeview控件的基本应用&#xff0c;可以用于商品分类、文件分类等等。 2.辅助决策 treeview可以组成决策树&#xff0c;用来帮助人们做选择。比如说今天中午吃什么菜&#xff1f; 如果我来选择的话&#xff0c;那就是&#xff1a;不吃辣-鲁菜-糖醋鲤鱼。 3.求解算…

C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测 效果 模型信息 Model Properties ------------------------- date&#xff1a;2024-02-26T08:38:44.171849 description&#xff1a;Ultralytics YOLOv8s-obb model trained on runs/DOT…

【MySQL系列 05】Schema 与数据类型优化

良好的数据库 schema 设计和合理的数据类型选择是 SQL 获得高性能的基石。 一、选择优化的数据类型 MySQL 支持的数据类型非常多&#xff0c;选择正确的数据类型对于获得高性能至关重要。不管存储哪种类型的数据&#xff0c;下面几个简单的原则都有助于做出更好的选择。 1. …