Day3 DOM-节点操作

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.mzph.cn/news/731426.shtml

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

相关文章

2024年华为OD机试真题-提取字符串中的最长数学表达式并计算-Java-OD统一考试(C卷)

题目描述: 提取字符串中的最长合法简单数学表达式,字符串长度最长的,并计算表达式的值。如果没有,则返回0 简单数学表达式只能包含以下内容 0-9数字,符号 +-* 说明: 1. 所有数字,计算结果都不超过long 2. 如果有多个长度一样的,请返回第一个表达式的结果 3. 数学表达式…

day18_支付宝支付项目部署(保存支付信息,支付接口,支付宝异步回调)

文章目录 1 支付1.1 需求说明1.2 支付宝支付1.2.1 产品介绍产品特色使用示例申请条件费率 1.2.2 接入准备1.2.3 手机网站支付快速接入1.2.4 官方demo研究 1.3 环境搭建(service-pay)1.4 后端接口1.4.1 保存支付信息实现流程说明查询订单接口开发openFeign接口定义代码实现添加依…

Rust:Arc::new(...) 生成的变量保存在堆上吗?

是的&#xff0c;当你使用 Arc::new(...) 在 Rust 中创建一个新的 Arc&#xff08;Atomic Reference Counted&#xff09;时&#xff0c;传递给 Arc::new 的数据&#xff08;或其副本&#xff09;会被分配到堆上。Arc 是一个引用计数智能指针&#xff0c;它允许数据在多个所有者…

Kafka MQ 主题和分区

Kafka MQ 主题和分区 Kafka 的消息通过 主题 进行分类。主题就好比数据库的表&#xff0c;或者文件系统里的文件夹。主题可以被分为若干个 分区 &#xff0c;一个分区就是一个提交日志。消息以追加的方式写入分区&#xff0c;然 后以先入先出的顺序读取。要注意&#xff0c;由…

新一代 Git 工具,AI 赋能!深度集成、简化操作 | 开源日报 No.194

gitbutlerapp/gitbutler Stars: 7.2k License: NOASSERTION gitbutler 是一个基于 Git 的版本控制客户端。旨在为现代工作流程构建一个全新的 Git 分支管理工具。 虚拟分支&#xff1a;可以同时在多个分支上工作&#xff0c;而无需不断切换分支简化提交管理&#xff1a;通过拖…

勒索软件事件手册:综合指南

近年来&#xff0c;勒索软件攻击的频率和复杂程度都急剧增加。这些攻击的影响可能是毁灭性的&#xff0c;从经济损失到严重的运营中断。 这就是为什么对于希望防范这种网络安全威胁的企业来说&#xff0c; 强大的勒索软件事件响应手册是不可谈判的。 本指南旨在深入了解勒索软…

项目管理技巧分享:如何有效拆分复杂项目?

项目经理需要理清三个问题&#xff1a;1.项目的达成目标是什么&#xff0c;2.项目执行周期有多长&#xff0c;3.项目预计成本是多少&#xff1f;复杂项目在管理执行上难度都较大&#xff0c;通常需要进行分解&#xff0c;并且这个过程离不开项目管理系统的支持。这篇文章告诉你…

《解密云计算:企业之选》

前言 在当今数字化时代,企业面临着巨大的数据处理压力和信息化需求,传统的IT架构已经无法满足日益增长的业务需求。在这样的背景下,越来越多的企业开始转向云计算,以实现灵活、高效和可扩展的IT资源管理和利用。 云计算 云计算是一种基于互联网的计算模式,它通过将数据、…

【字符串】【分类讨论】【KMP】1163. 按字典序排在最后的子串

作者推荐 视频算法专题 本文涉及知识点 字符串 字典序 分类讨论 本题无法使用KMP&#xff0c;因为t1不段变化。 LeetCode1163. 按字典序排在最后的子串 给你一个字符串 s &#xff0c;找出它的所有子串并按字典序排列&#xff0c;返回排在最后的那个子串。 示例 1&#xf…

ajax中各个参数的含义是什么?

在 AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;中&#xff0c;当使用不同的方法或库来发送请求时&#xff0c;参数会有所不同。但是&#xff0c;如果我们以 jQuery 的 $.ajax 方法为例&#xff0c;我们可以详细解释其中一些常见的参数及其含义&#xff1a; u…

Windows 安装 Xinference

Windows 安装 Xinference 0. 引言1. 创建虚拟环境2. 安装 pytorch3. 安装 llama_cpp_python4. 安装 chatglm-cpp5. 安装 Xinference6. 设置 model 路径7. 启动 Xinference8. 查看 Cluster Information 0. 引言 Xorbits Inference&#xff08;Xinference&#xff09;是一个性能…

伊理威科技:新手开抖店的教程

在数字浪潮中&#xff0c;抖音小店如星火燎原&#xff0c;吸引无数创业者。你是否也心潮澎湃&#xff0c;想要一试身手?别急&#xff0c;让我们一步步揭开开店的神秘面纱。 注册流程。想象一下&#xff0c;你只需在抖音平台上点击“我要开店”&#xff0c;按提示填写相关信息&…

物联网在智慧城市建设中的关键作用:连接、感知、智能响应

一、引言 随着信息技术的飞速发展&#xff0c;物联网&#xff08;IoT&#xff09;技术已经渗透到我们生活的方方面面&#xff0c;特别是在智慧城市建设中发挥着至关重要的作用。智慧城市是指通过运用先进的信息和通信技术&#xff0c;实现城市基础设施、公共服务、交通管理、环…

opencv dnn模块 示例(24) 目标检测 object_detection 之 yolov8-pose 和 yolov8-obb

前面博文【opencv dnn模块 示例(23) 目标检测 object_detection 之 yolov8】 已经已经详细介绍了yolov8网络和测试。本文继续说明使用yolov8 进行 人体姿态估计 pose 和 旋转目标检测 OBB 。 文章目录 1、Yolov8-pose 简单使用2、Yolov8-OBB2.1、python 命令行测试2.2、opencv…

LangChain Experssion Language之How to(二)

目录 LangChain Experssion Language简介 LangChain Experssion Language示例大赏 Create a runnable with the `@chain` decorator:chain chain Add fallbacks:出错了怎么回退 Stream custom generator functions:让答案变得流式一些 Inspect your runnables:chain长…

css clip-path polygon属性实现直角梯形

2024.3.8今天我学习了如何用css实现直角梯形的效果&#xff0c; 效果&#xff1a; 具体实现原理&#xff1a; 一、需要三个div&#xff1a; 外面一个大的div&#xff0c;里面左右两个小的div 我们需要先把第一个div变成直角梯形&#xff1a; 大概是这样&#xff0c;设置好之…

npm ERR! errno -13具体问题处理

npm ERR! errno -13具体问题处理 出现问题的报错 npm ERR! code EACCES npm ERR! syscall open npm ERR! path /Users/xxxx/.npm/_cache/index-v5/c6/06/xxxxx npm ERR! errno -13 npm ERR! npm ERR! Your cache folder contains root-owned files, due to a bug in npm ERR! …

visual studio 将编译后的dll等文件自动复制到指定目录

编译后的文件dll等总要手动复制到指定目录下&#xff0c;为了解决这一繁琐的操作&#xff0c;可以直接设置在编译完成后&#xff0c;自动复制到目标目录 - 在解决方案资源管理器&#xff0c;选中项目右键-》选中属性-》在弹出的面板选择生成事件 - 在后期生成事件命令行里填写…

Java数值格式化前面补零

使用String类的format方法 Java中的String类提供了一个format方法&#xff0c;可以用来格式化字符串。我们可以使用该方法来进行数值前面补零的操作。 int number 5; String formattedNumber String.format("%02d", number); System.out.println(formattedNumber)…

PCM会重塑汽车OTA格局吗(1)

目录 1.汽车OTA概述 2.ST如何考虑OTA&#xff1f; 2.1 Stellar四大亮点 2.2 PCM技术视角下的OTA 3.小结 1.汽车OTA概述 随着智能网联汽车的飞速发展&#xff0c;汽车OTA也越来越盛行&#xff1b; 目前来讲OTA分为FOTA和SOTA(Software-over-the-air)两种&#xff0c;区别…