Selenium WebDriver中的DOM是什么:结构、全称
Selenium WebDriver中的DOM是什么?
Selenium WebDriver中的DOM是使用HTML5和JavaScript进行Web开发的重要组成部分。DOM的全称是Document Object Model。DOM不是计算机科学概念。它是一套简单的接口,在Web开发者之间标准化,用于使用JavaScript访问和操作HTML或XML中的文档。
这些标准帮助开发者构建网页,而无需担心实现细节。参与标准化这些接口的组织包括Mozilla、Apple、Microsoft、Google、Adobe等。然而,W3C才是正式制定标准并发布标准——参见此处(https://dom.spec.whatwg.org/)。
本教程旨在涵盖HTML文档结构的基本概念以及如何使用JavaScript对其进行操作。本教程将涵盖以下主题:
理解DOM结构
如果您正在构建涉及JavaScript脚本的任何网站,您需要理解DOM结构。如果您正在执行以下一项或多项复杂任务,理解DOM就更加重要了——
- 开发无需刷新整个页面即可持续更新的内容——例如您用户投资组合中所有股票的当前价格
- 开发高级用户交互,例如动态添加或修改内容——例如向投资组合中添加更多股票的功能
- 开发用户可自定义的内容——例如更改布局,以便共同基金投资组合显示在股票投资组合之前
- 在您的网站中开发响应式内容,从而使您的网站能够自动适应不同的媒体屏幕,例如iPhone、桌面、平板电脑等。
一个基本的HTML页面
<!DOCTYPE html> <meta charset="UTF-8"> <html> <head> <title>my page title</title> </head> <body> <article> <p> my first article </p> </article> <aside>side bar content</aside> </body> </html>
它在浏览器DOM解析器看来是什么样的?
html > head > title > body > aside > article > p
如何访问body元素?
<script> var body = window.document.body; </script>
如何说“Hello World”?
<script> var body = document.querySelector("body > article > p").innerHTML = "Hello World!"; </script>
最后,整个HTML文件将显示如下
打开Windows记事本,并在其中粘贴以下内容。然后将文件另存为“MyFileNewFile.html”(确保您的文件名以.html结尾)。
<!DOCTYPE html> <meta charset="UTF-8"> <html> <head> <title>my page title</title> </head> <body> <article><p>my first article</p></article> <aside>side bar content</aside> <script> var body = document.querySelector("body > article > p").innerHTML = "Hello World!"; </script> </body> </html>
最后,只需使用您喜欢的任何浏览器打开该文件,您就会看到“Hello World!”
Window(窗口)
Window是包含DOM中document对象的对象。它位于所有对象的顶层。
从给定的文档获取窗口对象
<script> var window = document.defaultView; </script>
在标签式环境中,每个标签都有自己的窗口对象。但是,如果有人想捕获和实现window.resizeTo和window.resizeBy等事件,它们适用于整个窗口,而不是单独的标签。
DOM中Window对象的属性
window.localStorage – 提供对浏览器本地存储的访问。本地存储可用于从会话中存储和检索数据。
<script> window.localStorage.setItem('name','xyz'); var name = window.localStorage.getItem('name'); </script>
window.opener – 获取打开此窗口的窗口对象的引用(通过单击链接或使用window.open方法)
Window对象的有用方法
window.alert() – 显示带有消息的警报对话框。
<script> window.alert('say hello'); </script>
Window对象公开了许多有用的事件。我们将在“高级主题”下的“事件”部分讨论它们。
文档
Document标志着DOM树的开始。Document是DOM中的第一个节点。它具有许多方法和属性,其范围适用于整个文档,例如URL、getElementById、querySelector等。
DOM中Document对象的属性
Document.documentURI和Document.URL – 它们都返回文档的当前位置。但是,如果文档不是HTML类型,Document.URL将不起作用。
Document.activeElement – 此方法返回DOM中获得焦点的元素。这意味着如果用户正在文本框中输入,Document.activeElement将返回该文本框的引用。
Document.title – 用于读取或设置给定文档的标题。
Document对象的有用方法
Document.getElementById(String id) – 这是迄今为止在DOM操作中最相关和最有用的方法。它用于通过其唯一标识符查找DOM树中的元素。查找是区分大小写的,即在以下示例中,“<div id=’introDiv’>”元素不能使用IntroDiv、introdiv或iNtrodiv等词来查找。
<!DOCTYPE html> <meta charset="UTF-8"> <html> <head></head> <body> <div id='introDiv'></div> <script> var label = Document.getElementById('introDiv'); label.setInnerHTML('say hello again'); </script> </body> </html>
Document.querySelectorAll(String selector) – 这是另一种广泛使用的方法,用于根据CSS选择器的规则选择一个或多个元素(如果您熟悉jQuery的$符号,它本身就使用此方法)。我们不会深入探讨CSS选择器。CSS选择器是一组规则,您可以通过这些规则获得一组相似的元素(基于选择器规则)。我们在“Hello World”部分之前已经使用过此方法。
元素
DOM中的Element对象
Element是文档DOM树中由节点表示的任何对象。一如既往,Element对象本身只是浏览器和HTML文档之间属性、方法和事件的契约。有特殊种类的Element,如HTMLElement、SVGElement、XULElement等。本教程中我们将只关注HTMLElement。
DOM中Element对象的属性
Element.id – 此属性可用于设置或读取HTML元素的“ID”(唯一标识符)。ID在DOM树中的元素之间必须是唯一的。如前所述,ID也用于Document.getElementById方法来选择DOM树中的特定Element对象。
HTMLElement.contentEditable – 元素的contentEditable属性决定该元素的内容是否可编辑/可修改。此属性可以按如下所示脚本设置。此属性还可用于确定给定元素是否可编辑。尝试在任何HTML主体中运行以下脚本,您会注意到您可以编辑主体的任何内容。
<script> document.body.contentEditable = true; </script>
Element.innerHTML – innerHTML是我们用于访问元素内HTML内容的另一个重要属性。它还用于设置元素的新HTML内容。它广泛用于设置/更改数据字段的内容。例如,如果您希望您的网页每小时更新孟买市的温度,您可能每小时运行以下示例中的脚本。
<!DOCTYPE html> <meta charset="UTF-8"> <html> <head> <title>my page title</title> </head> <body> <section> <h1>Mumbai</h1> <h2>Temperature</h2> <span id='tempValue'></span><sup>o</sup>C </section> <script> document.getElementById('tempValue').innerHTML = '26'; </script> </body> </html>
Element对象的有用方法
HTMLElement.blur() & HTMLElement.focus() – blur和focus方法分别用于从HTML元素中移除焦点或给予焦点。这些方法最广泛地用于数据录入网页中文本框之间的焦点移动。
Element.querySelectorAll – 此方法与文档对象已讨论的querySelector方法类似。但是,此方法会将搜索范围限制在元素本身的后代内。
DOM调试
Google Chrome、Mozilla Firefox、Internet Explorer(10或更高版本)或Safari的开发者工具允许在浏览器内轻松调试。有时不同的浏览器对相同的HTML标记的解释不同,这时调试可以帮助您检查DOM被该特定浏览器DOM引擎解释后的样子。
现在,让我们假设您想将上一个示例中的温度值从26摄氏度更改为32摄氏度。我们将采取几个简单的步骤来完成。此处显示的截图来自Mozilla的Firefox——但是,在所有其他浏览器中,步骤是相同的。
- 使用浏览器打开MyFileNewFile.html(或您在教程中为HTML文件指定的任何名称)
-
用鼠标右键单击温度值26摄氏度,然后单击“检查元素”
-
请注意,您选择“检查元素”的元素将在浏览器中高亮显示(调试器窗口通常出现在屏幕底部)
-
通过单击旁边的倾斜三角形来打开<span>元素
-
选择您想要编辑的内容并双击它。您将可以选择更改文本。按照下面的动画图像中的说明进行操作。
-
注意HTML页面内容的更改。您现在可以关闭调试窗口。
请注意,您的更改仅在此会话中有效。一旦您重新加载或刷新(按F5)页面,更改就会恢复。这表明您并未更改实际的HTML源,而只是更改了浏览器本地的解释。
作为一项有趣的练习,请尝试执行以下操作。在浏览器中打开www.facebook.com,并使用调试器工具获得以下结果——注意它如何显示“我已破解Facebook”。
DOM事件
DOM中的事件是什么?
事件是一种编程模型,其中用户触发(或浏览器页面生命周期触发)的事件作为消息进行广播。例如,当页面加载完成时,它会触发window.load事件;类似地,当用户单击按钮时,该<input>元素的click事件将被触发。
这些消息可以被任何JavaScript代码拦截,然后可以采取开发者定义的动作。例如,如果您希望网页上的数字仅在用户单击按钮时更新。您可以通过以下任何方法来实现——
- 将操作分配给HTML元素的onclick事件
- 使用addEventListener方法将操作分配给click事件
方法 1
<!DOCTYPE html> <html> <head> <title>my page title</title> </head> <body> <section> <h1>Mumbai<h1> <h2>Temperature</h2> <span id='tempValue'></span><sup>o</sup>C <br/> <br/> <button onclick='onRefreshClick()'>Refresh</button> </section> <script> document.getElementById('tempValue').innerHTML = '26'; function onRefreshClick(e) { document.getElementById('tempValue').innerHTML = '32'; } </script> </body> </html>
方法 2
<!DOCTYPE html> <html> <head> <title>my page title</title> </head> <body> <section> <h1>Mumbai<h1> <h2>Temperature</h2> <span id='tempValue'></span><sup>o</sup>C <br/> <br/> <button id='btnRefresh'>Refresh</button> </section> <script> document.getElementById('tempValue').innerHTML = '26'; document.getElementById('btnRefresh').addEventListener('click', function(event) { document.getElementById('tempValue').innerHTML = '32' },false); </script> </body> </html>
DOM故障排除
问:我如何知道元素是否存在?
答:尝试使用任何选择器查找元素,并检查返回的元素是否为null。请参见下面的示例——
if(document.getElementById("elementIDWhichIsNotPresentInDOM") === null) { //do something }
问:我收到TypeError:document.getElementByID不是一个函数……
答:确保方法名称与API方法完全匹配。就像上面的问题一样——它是getElementById,而不是getElementByID。
问:children和childNodes有什么区别?
答:children方法获取调用元素内的所有元素的集合。返回的集合是HTMLCollection类型。但是,childNodes方法获取调用元素内的所有节点的集合。将以下脚本添加到我们的示例中,看看区别——
childNodes方法返回14个项目
document.write("Using childNodes method") document.write("<br>"); document.write("<br>"); for(i=0;i<document.getElementsByTagName("section")[0].childNodes.length;i++) { document.write((i+1)+"."); document.write(document.getElementsByTagName("section")[0].childNodes[i].toString()); document.write("<br>"); } document.write("<br>"); document.write("Number of nodes in a section " + document.getElementsByTagName("section")[0].childNodes.length);
而children方法只返回7个项目
document.write("Using children method") document.write("<br>"); document.write("<br>"); for(i=0;i<document.getElementsByTagName("section")[0].children.length;i++) { document.write((i+1)+"."); document.write(document.getElementsByTagName("section")[0].children[i].toString()); document.write("<br>"); } document.write("<br>"); document.write("Number of nodes in a section " + document.getElementsByTagName("section")[0].children.length);
问:我收到Uncaught TypeError:无法读取未定义属性‘innerHTML’……
答:请确保您正在调用innerHTML属性的HTMLElement实例在初始声明之后已设置。此错误通常发生在以下场景。看看下一块代码如何避免此错误……
var element; if(false) //say condition was false { element = document.getElementById('tempValue1'); } element.innerHTML = '32';
var element = null; if(false) //say condition was false { element = document.getElementById('tempValue1'); } if(element != null) { element.innerHTML = '32'; }
摘要
- 在本教程中,我们了解了DOM是什么,以及它对于构建动态网页来说是多么重要的概念。
- 我们还涉及了Window、Document和Element等DOM元素类型。
- 我们学习了每种类型提供的一些有用的DOM方法和属性。
- 我们看到了大多数浏览器如何提供开发者工具来操作互联网上可用的任何网页——从而学会了调试和解决我们自己网站的问题。
- 我们还简要介绍了DOM事件机制。
- 最后,我们介绍了一些DOM故障排除项目。
- 互联网上充满了DOM相关的资源。Mozilla开发者网络提供了最好的、最新的参考资料之一。请参阅——https://mdn.org.cn/en-US/docs/Web/API/Document_Object_Model