JavaScript DOM
内容提要 1 三位一体的网页 :HTML/CSS/JavaScript 2 DOM 和节点类型 3 获取元素 4 元素属性操作 : 动态修改元素属性 5 DOM 遍历 6 元素操作 : 动态创建标记 7 CSS 属性操作 8 事件 VCG DOM 2020/4/28 2
1 三位一体的网页 1 三位一体的网页 HTML 结构层 HTML 标记语言 : 描述页面的结构 如 <p>hello</p> CSS: 描述页面内容该如何呈现 如设置文本段的字体 字号 CSS 表示层 JavaScript 行为层 JavaScript: 负责内容应该如何响应 如点击文本段时, 显示 alert 对话框 VCG DOM 2020/4/28 3
DOM(Document Object Model, 文档对象模型 ) DOM 是针对 HTML/XML 文档, 提供方法允许开发人员添加 删除和修改页面中的某一部分 文档 (Document) 创建网页并把它加载到浏览器中, 网页文档被转换为一个 document 文档对象 对象 (Object) 将元素抽象为对象,HTML 中的每个元素都是一个对象, 作为 document 对象的属性 模型 (Model) 2 DOM 和节点类型 体现映射关系,DOM 将一份文档表示为一棵树 VCG DOM 2020/4/28 4
DOM 树的操作 2 DOM 和节点类型 使用 DOM 提供的方法操作 DOM 树, 添加 修改或删除页面元素和元素的属性 VCG DOM 2020/4/28 5
DOM 树 2 DOM 和节点类型 DOM 将一份文档表示为一棵树, 每个元素都被表示为一个节点 <html> <head> <title>sample Page</title> </head> <body> <p>hello World!</p> </body> </html> html head body title p Sample Page Hello world! VCG DOM 2020/4/28 6
节点类型 2 DOM 和节点类型 文档中的每一段标记都能通过树中的一个节点表示, 如文档节点 (Document) 注 释节点等 HTML 中, 常用元素节点 属性节点和文本节点操作文档 元素节点 html DOM 的原子 每个标签如 <p><ul><a> 被独立地表示为一类节点 元素节点的名字即为标签名 元素节点可以包含其他的元素节点 head body title p Sample Page Hello world! VCG DOM 2020/4/28 7
属性节点 2 DOM 和节点类型 属性节点用来对元素做出更具体的描述 标签的一个属性被表示为一个属性节点 属性总是被写在 HTML 的开标签中, 所以属性节点总是被包含在元素节点中 p 元素节点 <p title= Reminder > 降温, 多穿点 </p> title= Reminder 降温, 多穿点 属性节点 文本节点 VCG DOM 2020/4/28 8
文本节点 2 DOM 和节点类型 描述 HTML 开闭标签中的文本内容 文本节点总是被包含在元素节点内部, 元素节点不一定包含文本节点 p 元素节点 <p title= Reminder > 降温, 多穿点 </p> title= Reminder 降温, 多穿点 属性节点 文本节点 VCG DOM 2020/4/28 9
获取元素 3 获取元素 获取元素节点 对于 HTML 文件, 要对页面的元素进行操作, 首先要先进行获取 HTML 元素选择方法 方法名称 功能说明 1 getelementbyid() 通过 id 名称来选择元素, 每个元素有唯一的 id. 2 getelementsbytagname() 返回数组 通过标签的名称选择元素节点, 可能有多个, 选择的可以是个数组 3 getelementsbyclassname() 返回数组 通过 class 属性选择元素节点 4 getelementsbyname() 通过 name 属性获得元素节点 5 document.title 和 document.body 获取 title 和 body 节点 VCG DOM 2020/4/28 10
NodeList 对象 3 获取元素 是一种类数组对象, 用户保存一组有序的节点, 可以通过索引访问这些节点 具有 length 属性, 表示 NodeList 对象中的元素长度 具有动态性 是给予 DOM 结构动态执行查询的结果,DOM 结构的变化能够自动反应在 NodeList 对象中 VCG DOM 2020/4/28 11
getelementbyid(string) 3 获取元素 按元素 id 属性获取节点, 返回该元素节点对象 <h1>what to buy</h1> <p title="reminder">don't forget to buy this stuff</p> <ul id="purchases"> <li>a tin of beans</li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> Demo 4.1 <script> var purchases = document.getelementbyid("purchases"); alert(typeof purchases); // object </script> VCG DOM 2020/4/28 12
3 获取元素 getelementsbyclassname(string) 按元素 class 属性获取节点, 返回搜索到的元素节点数组 <h1>what to buy</h1> <p title="reminder">don't forget to buy this stuff</p> <ul id="purchases"> <li>a tin of beans</li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <script> var sales = document.getelementsbyclassname("sale"); for (var i = 0; i < sales.length; i++) { alert(sales[i].textcontent); // Cheese Milk } </script> Demo 4.1 VCG DOM 2020/4/28 13
getelementsbytagname(string) 按元素标签获取节点, 返回搜索到的元素节点数组 <h1>what to buy</h1> <p title="reminder">don't forget to buy this stuff</p> <ul id="purchases"> <li>a tin of beans</li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <script> var items = document.getelementsbytagname("li"); for (var i = 0; i < items.length; i++) { alert(items[i].textcontent); // A tin of beans Cheese Milk } </script> Demo 4.1 VCG DOM 2020/4/28 14
4 元素属性操作 对元素属性进行添加 修改删除或查询 如 title/name 的设置, 或表单 disabled 属性的添加或删除等操作 HTML 属性操作方法 方法名称 1 getattribute() 2 setattribute() 3 removeattribute() 4 hasattribute() 5 getattribute() 功能说明 获取元素的某个属性值 obj.getattribute( attr ) 设置元素的某个属性值 obj.setattribute( attr, 值 ) 删除元素的某个属性值 obj.removeattribute( attr ) 判断元素是否包含某个属性 obj.has Attribute( attr ) 获取元素的某个属性值 obj.getattribute( attr ) VCG DOM 2020/4/28 15
4 元素属性操作 object.hasattribute(string),object.getattribute(string) object.hasattribute(string) 返回 true/false, 判断元素是否拥有某属性 object.getattribute(string) 返回元素属性值 <h1>what to buy</h1> <p title="reminder">don't forget to buy this stuff</p> <ul id="purchases"> <li>a tin of beans</li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <script> var items = document.getelementsbytagname("li"); for (var i = 0; i < items.length; i++) { if (items[i].hasattribute("class")) { alert(items[i].getattribute("class")); // sale, sale important } } </script> Demo 4.2 VCG DOM 2020/4/28 16
object.setattribute(attr:string, value:string) 设置元素的 attr 属性为 value. 4 元素属性操作 <h1>what to buy</h1> <p title="reminder">don't forget to buy this stuff</p> <ul id="purchases"> <li>a tin of beans</li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <script> var items = document.getelementsbytagname("li"); for (var i = 0; i < items.length; i++) { items[i].setattribute("title", items[i].textcontent); alert(items[i].getattribute("title")); } </script> Demo 4.2 VCG DOM 2020/4/28 17
object.removeattribute(attr:string) 删除元素的 attr 属性 4 元素属性操作 <h1>what to buy</h1> <button id="button" disabled="disabled"> 按钮 </button> <script> var button = document.getelementbyid("button"); button.removeattribute("disabled"); </script> Demo 4.2 VCG DOM 2020/4/28 18
5 DOM 遍历 查找指定元素的父元素 子元素或兄弟元素 并非所有元素具有 id 等标记 需要遍历 DOM 树, 根据元素节点关系进行查询 节点属性 类别 节点属性 1 查找父元素 (parent) obj.parentnode 2 查找子元素 (child) obj.childnodes/firstchild/lastchild/ children/firstelementchild/lastelementchild 3 查找兄弟元素 (sibling) obj.previouelementsibling/nextelementsibling VCG DOM 2020/4/28 19
object.parentnode 5 DOM 遍历 返回当前节点的父节点和其对应的文本节点 Demo 4.3 <button class="btn" disabled="disabled"> 上一步 </button> <ul id="purchases"> <li>beans<span id="tin">/tin</span></li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <button class="btn" disabled="disabled"> 确认 </button> <script> tinspan = document.getelementbyid("tin"); beans = tinspan.parentnode; alert(beans.textcontent); // Beans/tin </script> VCG DOM 2020/4/28 20
5 DOM 遍历 5 DOM 遍历 object.children 返回当前节点的所有子节点与对应的文本节点 Demo 4.3 <button class="btn" disabled="disabled"> 上一步 </button> <ul id="purchases"> <li>beans<span id="tin">/tin</span></li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <button class="btn" disabled="disabled"> 确认 </button> <script> purchases = document.getelementbyid("purchases"); items = purchases.children; for (var i = 0; i < items.length; i++) { alert(items[i].textcontent); } </script> VCG DOM 2020/4/28 21
object.firstchild,object.firstelementchild object.firstchild 5 DOM 遍历 返回当前节点的首个子节点 ( 无文本节点 ) <button class="btn" disabled="disabled"> 上一步 </button> <ul id="purchases"> <li>beans<span id="tin">/tin</span></li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <button class="btn" disabled="disabled"> 确认 </button> <script> purchases = document.getelementbyid("purchases"); alert("firstchild: " + purchases.firstchild.textcontent); // alert("firstelementchild: " + purchases.firstelementchild.textcontent); </script> object.firstelementchild 返回当前节点的首个子节点与文本节点 // Beans/tin Demo 4.3 VCG DOM 2020/4/28 22
5 DOM 遍历 object.lastchild,object.lastelementchild object.lastchild 返回当前节点的末子节点 ( 无文本节点 ) object.lastelementchild 返回当前节点的末子节点与文本节点 VCG DOM 2020/4/28 23
5 DOM 遍历 object.previoussibling,object.previouselementsibling object.previoussibling 返回当前节点的前一个兄弟节点 ( 无文本节点 ) object.previouselementsibling 返回当前节点的前一个兄弟节点与文本节点 <button class="btn" disabled="disabled"> 上一步 </button> <ul id="purchases"> <li>beans<span id="tin">/tin</span></li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <button class="btn" disabled="disabled"> 确认 </button> <script> var itembean = document.getelementsbyclassname("sale")[0].previouselementsibling; alert(itembean.textcontent); // Beans/tin </script> Demo 4.3 VCG DOM 2020/4/28 24
5 DOM 遍历 object.nextsibling,object.nextelementsibling object.nextsibling 返回当前节点的后一个兄弟节点 ( 无文本节点 ) object.nextelementsibling 返回当前节点的后一个兄弟节点与文本节点 VCG DOM 2020/4/28 25
总表 5 DOM 遍历 VCG DOM 2020/4/28 26
6 元素操作 : 动态创建标记 使用 DOM 改变网页的结构和内容 在 DOM 树中动态插入 修改和删除节点 object.innerhtml 属性 用来读写给定元素内的 HTML 内容 Demo 4.4 <h1 id="title">what to buy</h1> <script> title = document.getelementbyid("title"); alert(title.innerhtml); settimeout(function() { title.innerhtml = " 天真冷!"; }, 2000); </script> VCG DOM 2020/4/28 27
createelement(nodename) 创建新的元素节点对象 createtextnode(text) 创建新的文本节点对象 <div id= container ></div> 例 : 将一段文本插入 container 元素 : 步骤一 : 创建一个新的 <p> 元素 ; 步骤二 : 创建一个文本节点对象 ; 步骤三 : 将文本节点对象插入 <p> 中 ; 步骤四 : 将 <p> 插入 container 中 Demo 4.5 parent.appendchild(child) 将 child 节点作为末子节点 插入 parent 节点中 <script> container = document.getelementbyid("container"); p = document.createelement("p"); text = document.createtextnode(" 天真冷 "); p.appendchild(text); container.appendchild(p); </script> VCG DOM 2020/4/28 28
6 元素操作 : 动态创建标记 parent.insertbefore(newelement, targetelement) 将新元素作为子节点插入到父元素的某个子元素之前 parent: 目标元素的父元素 ; newelement: 想插入的元素 ; targetelement: 想把新元素插入到哪个元素之前 Demo 4.6 <div id="container"><span id="question_mark">?</span></div> <script> container = document.getelementbyid("container"); p = document.createelement("p"); text = document.createtextnode(" 天真冷 "); p.appendchild(text); questionmark = document.getelementbyid("question_mark"); container.insertbefore(p, questionmark); </script> VCG DOM 2020/4/28 29
removechild, replacechild parent.removechild(element) 删除 parent 下的 element 子元素 6 元素操作 : 动态创建标记 parent.replacechild(newelement, oldelement) 用 newelement 替代 parent 下的 oldelement 子元素 VCG DOM 2020/4/28 30
<ul id="purchases"> <li>beans<span id="tin">/tin</span></li> <li class="sale">cheese</li> <li class="sale important">milk</li> </ul> <script> purchases = document.getelementbyid("purchases"); /* removechild */ beans = document.getelementsbytagname("li")[0]; purchases.removechild(beans); /* replacechild */ cheese = document.getelementsbytagname("li")[0]; milk = document.getelementsbytagname("li")[1]; purchases.replacechild(milk, cheese); </script> NodeList 对象的动态性 (11 页 ) VCG DOM 2020/4/28 31
element.style 7 CSS 属性操作 通过 element.style 属性查看和修改 CSS 样式每个 CSS 样式是 style 对象的属性, 每个样式使用驼峰标记法表示 如 :font-size -> fontsize; font-color -> fontcolor 只能查看和修改定义在 HTML 标签中 style 属性确定的样式 Demo 4.8 <p id="example" style="color: indianred; text-align: center; font: 12px 'Arial', sans-serif;"> 天真冷 </p> <script> example = document.getelementbyid("example"); alert(example.style.textalign); // center alert(example.style.fontsize); // 12px example.style.fontsize = "24px"; </script> VCG DOM 2020/4/28 32
8 事件 8 事件 事件处理函数 事件分类和应用 事件监听器 event 对象 VCG DOM 2020/4/28 33
JavaScript 与 HTML 之间的交互通过事件实现 事件 : 文档或浏览器窗口中发生的一些特定的交互瞬间, 如点击鼠标 按下键盘 提交表单 勾选复选框等 事件分类 鼠标事件 键盘事件 表单事件 编辑事件 页面事件 8 事件 VCG DOM 2020/4/28 34
调用方式 8 事件 使用方便 事件处理函数方式 在 script 标签中调用事件如 obj.onclick = function(){ } 在元素中调用事件如 <input type="button" onclick="alertfunction()" value=" 提交 "> 事件监听器方式 addeventlistener() removeeventlistener() 可以为一个元素添加多次相同事件 VCG DOM 2020/4/28 35
<p> 天真冷 ( 点击 )</p> <script> example = document.getelementbyid("example"); example.style.cursor = "pointer"; example.onclick = function (event) { example.innerhtml = ' 是的 ; } </script> Demo 4.9 VCG DOM 2020/4/28 36
事件处理函数 8 事件 在特定时间发生时调用特定的 JS 代码 在给元素添加事件处理函数后, 一旦事件发生, 相应的 JS 代码得到执行 被调用的 JS 代码可以返回值, 返回值将被传递给事件处理函数 事件处理函数名为 on + 事件名, 如 onclick/onkeyup 返回值为 true, 继续原来元素执行时间处理函数后的动作 ; 返回 false, 取消执行 对象与事件解绑 : 设置 object.event = null; 例 : 点击链接后不进行跳转 <a href="bjfu.edu.cn" id="href" onclick="return false;"> 跳转链接 </a> VCG DOM 2020/4/28 37
(1) 鼠标事件 8 事件 click mouseover mouseout mousedown mouseup mousemove 鼠标单击事件鼠标移入事件鼠标移出事件鼠标按下事件鼠标松开事件鼠标移动事件 VCG DOM 2020/4/28 38
(2) 键盘事件 8 事件 keydown keyup 按下键盘事件 松开键盘事件 场景 : 可通过键盘时间验证表单, 松开瞬间验证输入合法性并反馈错误提示 VCG DOM 2020/4/28 39
(2) 键盘事件例 : 即时验证输入框的手机号码合法性 1. 选择事件? - 需要在按下按钮并抬起后读取输入数据, 利用 RegExp 正则表达式方法检查合法性 故使用 onkeyup 事件处理函数 2. 选择反馈效果? - 验证失败输入框变红 在输入框上方显示提示文字等 3. 如何实现反馈效果? 提前写好错误 CSS 样式代码, 错误即修改 classname 的值, 添加或删除该样式 提前预留 <div> 等标签, 错误添加文本元素等 VCG DOM 2020/4/28 40
8 事件 键盘事件例 : 即时验证输入框的手机号码合法性 (2) 键盘事件例 : 即时验证输入框的手机号码合法性 只使输入框变红 CSS 样式定义 <style>.error_bg { border: 1px solid indianred!important; } </style> VCG DOM 2020/4/28 41
8 事件 8 事件 HTML5 新特性, 手机点击直接打开数字键盘 (2) 键盘事件例 : 即时验证输入框的手机号码合法性 只使输入框变红 <body> <input type="mobile" id="mobile-input" placeholder=" 请输入手机号码 "> <script> input = document.getelementbyid("mobile-input"); var mobilepattern = /1[2-9]\d{9}/; // 定义正则表达式 input.onkeyup = function(event) { // 在用户输入后 value = input.value; // 读取 input 的输入值 input.classname = input.classname.replace(/error_bg/, ); // 先删除 class 列表中的.error_bg, 防止多次添加 class if (!mobilepattern.test(value)) { // 正则表达式检查 input.classname += "error_bg"; // 如果错误, 为 input 添加 class } } </script> </body> Demo 4.10 VCG DOM 2020/4/28 42
(3) 表单事件 8 事件 blur focus change select 当前字段失去焦点 当前字段获得焦点 对于 <input><textarea> 元素, 在失去焦点且 value 值改变时触发 ;<select> 元素在选项改变时触发 选中文字 VCG DOM 2020/4/28 43
8.3 表单事件 8 事件 <input type="text" id="mobile-input"> <script> input = document.getelementbyid("mobile-input"); input.onblur = function () { input.setattribute("placeholder", " 失去焦点 "); } input.onfocus = function () { input.setattribute("placeholder", " 获得焦点 "); } input.onchange = function () { input.style.bordercolor = "indianred"; 获得选中文字 } input.onselect = function (event) { alert(" 你选择的文字 :" + window.getselection().tostring()); } </script> Demo 4.11 VCG DOM 2020/4/28 44
8.4 编辑事件 8 事件 copy selectstart contextmenu 复制 选中内容 鼠标右击 VCG DOM 2020/4/28 45
事件监听器 8 事件 具备给同一个元素添加多个相同事件的能力 如 : 为同一个按钮添加三次 onclick 事件, 事件处理函数方式只执行最后一次定义的函数代码 使用 addeventlistener() 将元素与事件绑定, 使用 removeeventlistener() 解除绑定 VCG DOM 2020/4/28 46
object.addeventlistener 8 事件 object.addeventlistener(event, function, false) object: 一个 DOM 对象 ; event: 字符串表示的事件名, 如 "click"/"keyup"; function: 函数, 常用匿名函数 ; false: 冒泡阶段调用, 常用 false. <button type="button" id="btn"> 多次点击 </button> <script> button = document.getelementbyid("btn"); button.addeventlistener("click", function() { alert(" 第一次 "); }, false); button.addeventlistener("click", function() { alert(" 第二次 "); }, false); </script> Demo 4.12 点击一次按钮, 弹出两次 alert VCG DOM 2020/4/28 47
8 事件 object.removeeventlistener object.removeeventlistener(event, function, false) object: 一个 DOM 对象 ; event: 字符串表示的事件名, 如 "click"/"keyup"; function: 函数 ; false: 冒泡阶段调用, 常用 false. VCG DOM 2020/4/28 48
event 对象 8 事件 event 对象 特定事件发生时, 发生事件的信息被作为参数传入事件处理函数 event 的常用属性 属性 type keycode shiftkey ctrlkey altkey 说明事件类型键码值是否按下 Shift 键是否按下 Ctrl 键是否按下 Alt 键 <p> 天真冷 ( 点击 )</p> <script> example = document.getelementbyid("example"); example.onclick = function (event) { example.innerhtml = ' 是的 ; alert(event.type); // click } </script> VCG DOM 2020/4/28 49
event.keycode 属性 8 事件 event.keycode 属性 : 返回键盘输入的键码值 按键键码 W 87 S 83 A 65 D 68 37 38 39 40 VCG DOM 2020/4/28 50
event.keycode 8 事件 event 对象例 : 显示 WASD/ 对应关系 var error = document.getelementbyid("error"); document.onkeydown = function (e) { if (e.shiftkey e.ctrlkey e.altkey) { alert(" 请不要按 Shfit/Ctrl/Alt 键 "); } } window.addeventlistener("keydown", function(e) { if (e.keycode == 37 e.keycode == 65) { error.innerhtml = " 上 "; } else if (e.keycode == 38 e.keycode == 87) { error.innerhtml = " 左 "; } else if (e.keycode == 39 e.keycode == 68) { error.innerhtml = " 右 "; } else if (e.keycode == 40 e.keycode == 83) { error.innerhtml = " 下 "; } }); Demo 4.13 VCG DOM 2020/4/28 51