(十六)

作者: xpwei | 来源:发表于2018-04-14 17:19 被阅读11次

查找元素

var div = document.getElementById("myDiv");//取得<div>元素的引用

IE8及较低版本不区分ID的大小写,因此“myDiv”和“mydiv”会被当做相同的元素ID。
如果页面中多个元素的ID值相同,getElementById()只返回文档中第一次出现的元素。IE7及较低版本还为此方法添加了一个有意思的“怪癖”:name特性与给定ID匹配的表单元素也会被该方法返回。如果有哪个表单元素的name特性等于指定的ID,而且该元素在文档中位于带有给定ID的元素前面,那么IE就会返回那个表单元素:

<input type="text" name="myElement" value="Text field">
<div id="myElement">A div</div>
document.getElementById("myElement ");

以上代码在IE7中结果会返回<input>元素;而在其他所有浏览器中,都会返回对<div>元素的引用。为了避免IE中存在的这个问题,最好的办法是不让表单字段的name特性与其他元素的ID相同。

var images = document.getElementsByTagName("img");
alert(images.length); //输出图表的数量
alert(images[0].src); //输出第一个图像元素的src 特性
aler t(images.item(0).src); //输出第一个图像元素的src 特性

HTMLCollection对象还有一个方法,叫做namedItem(),使用这个方法可以通过元素的name特性取得集合中的项:

<img src="myimage.gif" name="myImage">
var myImage = images.namedItem("myImage");
var myImage = images["myImage"];
var radios = document.getElementsByName("color");

特殊集合
除了属性和方法,document对象还有一些特殊的集合。这些集合都是HTMLCollection对象,为访问文档常用的部分提供了快捷方式:

  • document.anchors,包含文档中所有带name特性的<a>元素;
  • document.applets,包含文档中所有的<applet>元素,因为不再推荐使用<applet>元素,所以这个集合已经不建议使用了。
  • document.forms,包含文档中所有的<form>元素,与document.getElementsByTagName("form")得到的结果相同。
  • document.images,包含文档中所有的<img>元素,与document.getElementsByTagName("img")得到的结果相同。
  • document.links,包含文档中所有带href特性的<a>元素。

这个特殊集合始终都可以通过HTMLDocument对象访问到,而且,与HTMLcollection对象类似,集合中的项也会随着当前文档内容的更新而更新。

文档写入
有一个document对象的功能已经存在很多年了,那就是将输出流写入到网页中的能力。这个能力体现在下列4个方法中:write()、writeln()、open()、 close()。

Element类型
除了Document类型之外,Element类型就要算是Web编程中最常用的类型了。Element类型用于表现XML或HTML元素,提供了对元素标签名、子节点及特性的访问。

var div = document.getElementById("myDiv");
alert(div.tagName); //"DIV"
alert(div.tagName == div.nodeName); //true

这里的元素标签名是div,它拥有一个值为“myDiv”的ID。可是,div.tagName实际上输出的是“DIV”而非“div”。在HTML中,标签名始终都以全部大写表示;而在XML(有时候也包括XHTML)中,标签名则始终会与源代码中的保持一致。假如你不确定自己的脚本将会在HTML还是XML文档中执行,最好是在比较之前将标签转换为相同的大小写形式:

if (element.tagName == "div"){ //不能这样比较,很容易出错!
    //在此执行某些操作
}
if (element.tagName.toLowerCase() == "div"){ //这样最好
    //在此执行某些操作
}

HTML元素
所有HTML元素都由HTMLElement类型表示,不是直接通过这个类型,也是通过它的子类型来表示。HTMLElement类型直接继承自Element并添加了一些属性。

<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>
var div = document.getElementById("myDiv");
alert(div.id); //"myDiv""
alert(div.className); //"bd"
alert(div.title); //"Body text"
alert(div.lang); //"en"
alert(div.dir); //"ltr"

像下面这样通过为每个属性赋予新的值,也可以修改对应的每个特性:

div.id = "someOtherId";
div.className = "ft";
div.title = "Some other text";
div.lang = "fr";
div.dir ="rtl";

取得特性
操作特性的DOM方法主要有三个,分别是getAttribute()、setAttribute()、 removeAttribute()。

var div = document.getElementById("myDiv");
alert(div.getAttribute("id")); //"myDiv"
alert(div.getAttribute("class")); //"bd"
alert(div.getAttribute("title")); //"Body text"
alert(div.getAttribute("lang")); //"en"
alert(div.getAttribute("dir")); //"ltr"

在IE7及以前版本中,通过getAttribute()方法访问style特性或onclick这样的事件处理特性时,返回的值与属性的值相同。换句话说,getAttribute("style")返回一个对象,而getAttribute("obclick")返回一个函数。虽然IE8已经修复了这个bug,但不同IE版本间的不一致性,也是导致开发人员不使用getAttribute()访问HTML特性的一个原因。
在IE7及以前版本中,setAttribute()存在一些异常行为。通过这个方法设置class和style特性,没有任何效果,而使用这个方法设置事件处理程序特性时也一样。尽管到了IE8才解决这些问题,但我们还是推荐通过属性来设置特性。
IE6及以前版本不支持removeAttribute()。

attribute属性
Element类型是使用attributes属性的唯一一个DOM节点类型。attributes属性中包含一个NamedNodeMap,与NodeList类似,也是一个“动态”的集合。

  • getNamedItem(name):返回nodeName属性等于name的节点
  • removeNamedItem(name):从列表中移除nodeName属性等于name的节点
  • setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引
  • item(pos):返回位于数字pos位置处的节点。

attributes属性中包含一系列节点,每个节点的nodeName就是特性的名称,而节点的nodeValue就是特性的值。要取得元素的id特性,可以使用一下代码:

var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;

创建元素

var div = document.createElement("div");

元素的子节点

for (var i=0, len=element.childNodes.length; i < len; i++){
  if (element.childNodes[i].nodeType == 1){
      //执行某些操作
  }
}

Text类型
分割文本节点

var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); //"Hello"
alert(newNode.nodeValue); //" world!"
alert(element.childNodes.length); //2

Comment类型
注释在DOM中是通过Comment类型来表示的。

<div id="myDiv"><!--A comment --></div>
var div = document.getElementById("myDiv");
var comment = div.firstChild;
alert(comment.data); //"A comment"

另外,使用document.createComment()并为其传递注释文本也可以创建注释节点:

var comment = document.createComment("A comment ");

开发人员很少会创建和访问注释节点,因为注释节点对算法鲜有影响。此外,浏览器也不会识别位于</html>标签后面的注释。如果要访问注释节点,一定要保证它们是<html>元素的后代(即位于<html>和</html>之间)。

DOM操作技术
动态脚本

<script type="text/javascript" src="client.js"></script>
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "client.js";
document.body.appendChild(script);

尝试标准的DOM文本节点方法,因为除了IE(在IE中会导致抛出错误),所有浏览器都支持这种方式。如果这行代码抛出了错误(IE将<script>视为一个特殊的元素,不允许DOM访问其子节点),那么说明是IE,于是就必须使用text属性了。整个过程可以用以下函数来表示:

function loadScriptString(code) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    try {
        script.appendChild(document.createTextNode(code));
    } catch (ex) {
        script.text = code;
    }
    document.body.appendChild(script);
}
loadScriptString("function sayHi(){alert('hi');}");

这种方式加载的代码会在全局作用域中执行,而且当脚本执行后将立即可用。实际上,这样执行代码与在全局作用域中把相同的字符串传递给eval()是一样的。

动态样式

<link rel="stylesheet" type="text/css" href="styles.css">
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "style.css";
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);

与动态添加嵌入式脚本类似:

function loadStyleString(css) {
    var style = document.createElement("style");
    style.type = "text/css";
    try {
        style.appendChild(document.createTextNode(css));
    } catch (ex) {
        style.styleSheet.cssText = css;
    }
    var head = document.getElementsByTagName("head")[0];
    head.appendChild(style);
}
loadStyleString("body{background-color:red}");

如果专门针对IE编写代码,务必小心使用styleSheet.cssText属性。在重用同一个<style>元素并在此设置这个属性时,有可能会导致浏览器崩溃。同样,将cssText属性设置为空字符串也可能导致浏览器崩溃。

使用NodeList
下面代码会出现死循环:

var divs = document.getElementsByTagName("div"),
    i,
    div;
for (i = 0; i < divs.length; i++) {
    div = document.createElement("div");
    document.body.appendChild(div);
}

改为:

var divs = document.getElementsByTagName("div"),
    i,
    len,
    div;
for (i = 0, len = divs.length; i < len; i++) {
    div = document.createElement("div");
    document.body.appendChild(div);
}

这个例子中初始化了第二个变量len。由于len中保存着对divs.length在循环开始时的一个快照,因此就会避免上一个例子中出现的无限循环问题。
一般来说,应该尽量减少访问NodeList的次数。因为每次访问NodeList,都会运行一次基于文档的查询。所以,可以考虑将从NodeList中取得的值缓存起来。

相关文章

  • 2017-06-15

    十六行相 部派佛教的修证理论。指观四谛之境时所产生的十六种行相。又称十六行、十六行观、十六行相观、十六圣行、十六谛...

  • 二十六度与三十六度

    二十六度与三十六度 二十六度坐着欢笑着 三十六度皱着眉走着 二十六度一如既往的闲适 三十六度自始至终在奔忙 二十六...

  • 绕口令

    六十六头牛——六十六岁的陆老头,盖了六十六间楼,买了六十六篓油,养了六十六头牛,栽了六十六棵垂杨柳。六十六篓油,堆...

  • 绕口令😊

    六十六岁的陆老头,盖了六十六间楼,买了六十六篓油,养了六十六头牛,栽了六十六棵垂杨柳。六十六篓油,堆在六十六间楼;...

  • 十六岁的我们

    十六岁的我们是青春,十六岁的我们是最有趣的灵魂,十六岁的我们拥有着独特的十六岁。 十六...

  • 2018-04-19

    十六岁的她遇见了十六岁的他。 十六岁的她认识了十六岁的他。 然后,十六岁的她喜欢上了十六岁的他。 他们相识,相知....

  • 学写诗|诗色年华(二)

    平,中仄平平仄仄平。平平仄,中仄仄平平。 十六字令 十六字以言情,十六字以表志,十六字以叙事,十六字以画景。 伤 ...

  • 绕口令

    三十六,三十六,年年三十六,日日三十六,若无三十六,何以生? 八十一,八十一,九九八十一,年年八十一,日日八十一,...

  • 2019-10-14

    爱我中华 “五十六个民族,五十六只花,五十六个只弟姐妹都是一家,五十六和语...

  • 十六,十六

    电动车又要坏了,骑着的时候,发出很大的响声,中轴往前的部分,但是说不好究竟是哪儿。今天下班太晚了,本来是要去修车的...

网友评论

    本文标题:(十六)

    本文链接:https://www.haomeiwen.com/subject/znelkftx.html