document/node.getElementsByTagName
document/node.querySelector
,querySelectorAll
大部分时间里,为了与用户进行交互,我们需要找到元素并进行修改。
虽然我们可以使用childNodes,children等方式,但他们只允许在相邻的元素中进行移动。
幸运的是,我们有其他的全局方法可以实现这一点。
获取元素的最快方式是使用其 id。
下例将使用 id='info' 从document中搜索div标签。不管它在什么地方,始终都能被找到。
<body> <div id="info">Info</div> <script> var div = document.getElementById('info') alert( div.innerHTML ) </script></body>
注意,同一个id只应该出现一起。当然,你也可以破坏这个规则,但这么做的话根据浏览器 getElementById 会出现不同的加过。因此最好还是坚持标准规范,保证指定的 id 只有一个元素。
如果没有找到元素,将会返回null。
所有的浏览器都会隐式的为 id 创建一个变量。
举例说明,运行以下代码。它会输出 test。因为 a 是由IE生成的对元素的引用。
<div id="a">test</div><script> alert(a)</script>
运行下段代码在IE中可能会导致错误,请看下面的例子。
<div id="a">test</div><script> a = 5 // (x) alert(a)</script>
如果你从IE运行,它将不会工作。x行有错误的,因为:
但是你可以使用var a来代替a:
<div id="a">test</div><script> var a = 5 alert(a) // all fine</script>
IE教了我们其他的好的实验。
我们都知道window是全局对象。javaScript在最后会在window中搜索所有的东西。
那么window.window是什么,window === window.window 是否成立
逻辑上来看,它是相同的,但... 。
除了IE的大部分浏览器中,window.window只是对引用的一个钩子,window也是。因此 window === window.window,成立。
并且 window.window.window 也是跟 window.window 一样。
但是在IE,顶层的 window 是特殊的对象拥有着特殊的功能,然而 window.window 有点像标准的window对象。
你可以在IE中验证以下代码:
alert(window === window.window) // falsealert(window.window === window.window.window) // true为什么说它是重要的。
当你使用一个变量不适用 var 时,它会有一些功能及Bug,因为IE使用它自己的外部window对象对它进行处理。
其中最明显的有:
1. 对元素的id重新进行赋值 - IE会报错:
<div id="a">...</div><script> a = 5 // error in IE! Ok if "var a = 5" alert(a) // will never happen</script>2. 从外部window变量中对它进行递归遍历 - 下面的代码会在 IE<9 中死掉。
<script>// recurse is explicitly defined on the outer windowwindow.recurse = function(times) { if (times !== 0) recurse(times-1)}recurse(13)</script>该BUG在IE9中已修复。
document/node.getElementsByTagName
通过这个方法可以使用特定的标签名进行检索,结果为array-like的元素集合。
// get all div elementsvar elements = document.getElementsByTagName('div')
下例会展示出如何从 document 中检索出 INPUT 标签集合,并对它们进行遍历:
<table id="myTable"> <tr> <td>Your age:</td> <td> <label> <input type="radio" name="age" value="young" checked/> under 18 </label> <label> <input type="radio" name="age" value="mature"/> from 18 to 50 </label> <label> <input type="radio" name="age" value="senior"/> older than 60 </label> </td> </tr></table><script>var elements = document.getElementsByTagName('input') for(var i=0; i<elements.length; i++) { var input = elements[i] alert(input.value+': '+input.checked) }</script>
我们也可以直接访问第一个元素:
var element = document.getElementsByTagName('input')[0]
可以通过使用 '*' 而不是标签来获取所有的元素:
// get all elements in the documentdocument.getElementsByTagName('*')
getElementsByTagName可以被 document 调用,它也可以被普通的DOM元素进行调用。
下例演示getElementsByTagName
如何在普通的DOM元素中进行调用的。
<ol id="people"> <li>John</li> <li>Rodger</li> <li>Hugo</li></ol><script> var elem = document.getElementById('people') var list = elem.getElementsByTagName('li') alert(list[0].innerHTML)</script>
在elem中通过使用elem.getElementsByTagName('li')查找所有的 LI。点号之前的被称为上下文对象。
元素是支持 name attribute的,可以通过name来查询它们。
上面的例子我们还可以使用以下代码:
var elements = document.getElementsByName('age')
document/node.getElementsByClassName
这个方法在除了IE<9以外的所有的浏览器所支持。
它根据 class 名称进行搜索,不是attribute。尤其是,它支持多个类。
下面的例子将演示它如何根据 class名 查找对应元素。
请不要使用 IE<9 浏览器:
<div class="a b c">Yep</div><script>alert( document.getElementsByClassName('a')[0].innerHTML )</script>
跟getElementsByTagName
一样它也可以从普通的DOM元素进行查找
。
document/node.querySelector
,querySelectorAll
querySelector 和querySelectorAll可以根据 CSS3 语法检索元素。
querySelector 只返回第一个元素(深度优先),querySelectorAll 返回全部。
它们运行在除了IE<8以外的所有的浏览器里。下面列表为IE支持的情况:
下面的代码会查询到最后的元素为 LI 并且父节点为 UL 的所有匹配元素。他们都可以再IE8里运行。
<ul> <li>The</li> <li>Test</li></ul><ul> <li>Is</li> <li>Passed</li></ul><script> var elements = document.querySelectorAll('UL > LI:last-child') for(var i=0; i<elements.length; i++) { alert(elements[i].innerHTML ) }</script>
querySelector 是querySelectorAll('...')[0] 的缩写。
现代浏览器都支持强力的XPath搜索,XPath在xml世界中是一个通用的DOM检索工具。大部分也可以在HTML中使用该工具。
下面的例子将会使用XPath语法检索出所有包含XPath的 H3 元素。
var result = document.evaluate("//h3[contains(text(),'XPath')]", document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)for (var i=0; i<result.snapshotLength; i++) { alert(result.snapshotItem(i).innerHTML)}
唯一的里外是IE(包含9),它支持XML文档。文档可以使用 xmlhttpRequest(Ajax) 技术从服务器进行加载,但如果要在文档中进行搜索,你需要显示的把该网页载入到XML文档对象。
在现实生活中 querySelector 可以更加方便的解决任务,但多了解不同的实现方式始终是有好处的。
所有的DOM搜索,都会匹配多个元素,会返回一个 array-like集合,通过它有获取长度和下标功能。它也可以像数组一样使用 for 进行遍历。
但是下标和长度属性是它和数组仅有的共同点,并且返回的元素集合有一个特殊的类型 NodeList 或 HTMLCollection。
因此它没有 push,pop 或Javascript Array对象的其他属性。
相反,通过getElementsBy* 方法查询后的结果集是活着的。你可以选择元素并更改文档 - 之前查询后的结果也会自动进行更新。
下例将会说明当元素被移除后结果集的长度是如何被更改的。
<div id="outer"> <div id="inner">Info</div></div><script> var outerDiv = document.getElementById('outer') var divs = document.getElementsByTagName('div') alert(divs.length) outerDiv.innerHTML = '' // clear inner div alert(divs.length)</script>
这个特性只存在于集合中。如果你得到一个元素的引用,则该引用不会成为 null。例如,元素elem = document.getElementById('inner') 当外部 div 被清除后它也会一直存在。
但是 querySelectorAll 有些特殊。因为性能原因,它会返回 非活跃 的 NodeList。它是通用规则的一个例外。
考虑以下的HTML:
<!DOCTYPE HTML><html><body><label>The table</label><form name="age-form"> <table id="age-table"> <tr> <td id="age-header">Your age:</td> <td> <label> <input type="radio" name="age" value="young"/> under 18 </label> <label> <input type="radio" name="age" value="mature"/> 18 to 50 </label> <label> <input type="radio" name="age" value="senior"/> after 60 </label> </td> </tr> </table></form></body>
下面为根据上面的DOM结构的一些练习。
查找表格中的所有的 laben 元素。结果是 label 类型的数组。
参考答案
编写一个函数
checkInsideTable(id)
,当传一个id,并且该id的元素在id为age-table的表格中存在的话返回true。如
新闻热点
疑难解答