javascript与DOM:

我们来个例子,一个HTML里包含一段文本和一个无序的列表。

<p id="intro">My first paragraph...</p>
<ul>
      <li>List item 1</li>
      <li>List item 1</li>
      <li>List item 1</li>
      <li>List item 1</li>
      <li>List item 1</li>
</ul>  

上面例子里,我们使用getElementById DOM方法来访问p段落。

var pDom = document.getElementById('intro'); // 现在有了该DOM节点,这个DOM节点展示的是该信息段落

变量pDom现在已经引用到该DOM节点上了,我们可以对该节点做很多事情,比如查询内容和属性,或者其它任何操作,甚至可以删除它,克隆它,或者将它移到到DOM树的其它节点上。

文档上的任何内容,我们都可以使用JavaScript和DOM API来访问,所以类似地,我们也可以访问上面的无序列表,唯一的问题是该元素没有ID属性,如果ID的话就可以使用相同的方式,或者使用如下getElementsByTagName方式:

var allU = document.getElementsByTagName('ul');  // 'getElementsByTagName'返回的是一个节点集合 - 和数组有些类似

getElementsByTagName

getElementsByTagName方法返回的是一个节点集合,和数组类似也有length属性,重要的一个特性是他是实时的——如果你在该元素里添加一个新的li元素,这个集合就会自动更新,介于他和数组类型,所以可以和访问数组一样的方法来访问,所以从0开始:

// 访问无序列表: [0]索引
var unorderedList = document.getElementsByTagName('ul')[0];
// 获取所有的li集合:
var allListItems = unorderedList.getElementsByTagName('li');
// 循环遍历
for (var i = 0, length = allListItems.length; i < length; i++) {
    // 弹出该节点的text内容
    alert(allListItems[i].firstChild.data);
} 

以下图例更清晰地展示了DOM获取的知识:

DOM穿梭

“穿梭”这个词主要是用来描述通过DOM查找节点,DOM API提供了大量的节点属性让我们来往上或者往下查询节点。

所有的节点都有这些属性,都是可以用于访问相关的node节点:

  1. Node.childNodes: 访问一个单元素下所有的直接子节点元素,可以是一个可循环的类数组对象。该节点集合可以保护不同的类型的子节点(比如text节点或其他元素节点)。
  2. Node.firstChild: 与‘childNodes’数组的第一个项(‘Element.childNodes[0]‘)是同样的效果,仅仅是快捷方式。
  3. Node.lastChild: 与‘childNodes’数组的最后一个项(‘Element.childNodes[Element.childNodes.length-1]‘)是同样的效果,仅仅是快捷方式。shortcut.
  4. Node.parentNode: 访问当前节点的父节点,父节点只能有一个,祖节点可以用‘Node.parentNode.parentNode’的形式来访问。
  5. Node.nextSibling: 访问DOM树上与当前节点同级别的下一个节点。
  6. Node.previousSibling: 访问DOM树上与当前节点同级别的上一个节点。

通过这张图,理解起来就简单多了,但有个非常重要的知识点:那就是元素之间不能有空格,如果ul和li之间有空格的话,就会被认为是内容为空的text node节点,这样ul.childNodes[0]就不是第一个li元素了。相应地,<p>的下一个节点也不是<ul>,因为<p>和<ul>之间有一个空行的节点,一般遇到这种情况需要遍历所有的子节点然后判断nodeType类型,1是元素,2是属性,3是text节点,详细的type类型可以通过此地址

    Node.ELEMENT_NODE == 1
    Node.ATTRIBUTE_NODE == 2
    Node.TEXT_NODE == 3
    Node.CDATA_SECTION_NODE == 4
    Node.ENTITY_REFERENCE_NODE == 5
    Node.ENTITY_NODE == 6
    Node.PROCESSING_INSTRUCTION_NODE == 7
    Node.COMMENT_NODE == 8
    Node.DOCUMENT_NODE == 9
    Node.DOCUMENT_TYPE_NODE == 10
    Node.DOCUMENT_FRAGMENT_NODE == 11
    Node.NOTATION_NODE == 12

操作元素

每个DOM节点都包括一个属性集合,大多数的属性都提供为相应的功能提供了抽象。例如,如果有一个带有ID属性intro的文本元素,你可以很容易地通过DOM API来改变该元素的颜色:

document.getElementById('intro').style.color = '#FF0000';

为了理解这个API的功能,我们一步一步分开来看就非常容易理解了:

var myDocument = document;
var myIntro = myDocument.getElementById('intro');
var myIntroStyles = myIntro.style;  

// 现在,我们可以设置颜色了:
myIntroStyles.color = '#FF0000';

现在,我们有了该文本的style对象的引用了,所以我们可以添加其它的CSS样式:

myIntroStyles.padding = '2px 3px 0 3px';
myIntroStyles.backgroundColor = '#FFF';
myIntroStyles.marginTop = '20px'; 

这里我们只是要了基本的CSS属性名称,唯一区别是CSS属性的名称如果带有-的话,就需要去除,比如用marginTop代替margin-top。例如,下面的代码是不工作的,并且会抛出语法错误:

myIntroStyles.padding-top = '10em';
// 产生语法错误:
// 在JavaScript里横线-是减法操作符
// 而且也没有这样的属性名称

属性可以像数组一样访问,所以利用这个知识我们可以创建一个函数来改变任何给定元素的样式:

function changeStyle(elem, property, val) {
    elem.style[property] = val; // 使用[]来访问属性
}

// 使用上述的函数:
var myIntro = document.getElementById('intro'); // 获取intro文本对象
changeStyle(myIntro, 'color', 'red');  

通常DOM操作都是改变原始的内容,这里有几种方式来实现这个,最简单的是使用innerHTML属性,例如:

var myIntro = document.getElementById('intro');  

// 替换当前的内容
myIntro.innerHTML = 'New content for the <strong>amazing</strong> paragraph!';  

// 添加内容到当前的内容里
myIntro.innerHTML += '... some more content...';

唯一的问题是该方法没在规范里定义,而且在DOM规范里也没有定义,如果你不反感的话请继续使用,因为它比我们下面要讨论其它的方法快多了。

Node节点

var myIntro = document.getElementById('intro');  

// 添加内容
var someText = 'This is the text I want to add';
var textNode = document.createTextNode(someText);
myIntro.appendChild(textNode);

这里我们使用了appendChild方法将新text节点附件到文本字段,这样做比非标准的innerHTML方法显得有点长,但了解这些原理依然很重要,这里有一个使用DOM方法的更详细例子:

var myIntro = document.getElementById('intro');  

// 添加新连接到文本节点
// 首先,创建新连接元素
var myNewLink = document.createElement('a'); // <a/>
myNewLink.href = 'http://google.com'; // <a href="http://google.com"/>
myNewLink.appendChild(document.createTextNode('Visit Google'));
// <a href="http://google.com">Visit Google</a>  

// 将内容附件到文本节点
myIntro.appendChild(myNewLink);

另外DOM里还有一个insertBefore方法用于再节点前面附件内容,通过insertBefore和appendChild我们可以实现自己的insertAfter函数:

// 'Target'是DOM里已经存在的元素
// 'Bullet'是要插入的新元素

function insertAfter(target, bullet) {
    target.nextSibling ?
        target.parentNode.insertBefore(bullet, target.nextSibling)
        : target.parentNode.appendChild(bullet);
}  

// 使用了3目表达式:
// 格式:条件?条件为true时的表达式:条件为false时的表达式

上面的函数首先检查target元素的同级下一个节点是否存在,如果存在就在该节点前面添加bullet节点,如果不存在,就说明target是最后一个节点了,直接在后面append新节点就可以了。DOM API没有给提供insertAfter是因为真的没必要了——我们可以自己创建。

DOM操作有很多内容,上面你看到的只是其中一部分。

Event事件

浏览器事件是所有web程序的核心,通过这些事件我们定义将要发生的行为,如果在页面里有个按钮,那点击此按钮之前你需要验证表单是否合法,这时候就可以使用click事件,下面列出的最标准的事件列表:

注:正如我们上章所说的,DOM和JavaScript语言是2个单独的东西,浏览器事件是DOM API的一部分,而不是JavaScript的一部分。

鼠标事件

  1. mousedown’ – 鼠标设备按下一个元素的时候触发mousedown事件。
  2. mouseup’ – 鼠标设备从按下的元素上弹起的时候触发mouseup事件。
  3. click’ – 鼠标点击元素的时候触发click事件。
  4. dblclick’ – 鼠标双击元素的时候触发dblclick事件。
  5. mouseover’ – 鼠标移动到某元素上的时候触发mouseover事件。
  6. mouseout’ – 鼠标从某元素离开的时候触发mouseout事件。
  7. mousemove’ – 鼠标在某元素上移动但未离开的时候触发mousemove事件。

键盘事件

  1. keypress’ – 按键按下的时候触发该事件。
  2. keydown’ – 按键按下的时候触发该事件,并且在keypress事件之前。
  3. keyup’ – 按键松开的时候触发该事件,在keydown和keypress事件之后。

表单事件

  1. select’ – 文本字段(input, textarea等)的文本被选择的时候触发该事件。
  2. change’ – 控件失去input焦点的时候触发该事件(或者值被改变的时候)。
  3. submit’ – 表单提交的时候触发该事件。
  4. reset’ – 表单重置的时候触发该事件。
  5. focus’ – 元素获得焦点的时候触发该事件,通常来自鼠标设备或Tab导航。
  6. blur’ – 元素失去焦点的时候触发该事件,通常来自鼠标设备或Tab导航。

其它事件

  1. load’ – 页面加载完毕(包括内容、图片、frame、object)的时候触发该事件。
  2. resize’ – 页面大小改变的时候触发该事件(例如浏览器缩放)。
  3. scroll’ – 页面滚动的时候触发该事件。
  4. unload’ – 从页面或frame删除所有内容的时候触发该事件(例如离开一个页面)。

javascript --- javascript与DOM的更多相关文章

  1. 借助JavaScript中的Dom属性改变Html中Table边框的颜色

    借助JavaScript中的Dom属性改变Html中Table边框的颜色 -------------------- <html> <head> <title>我是页 ...

  2. JavaScript 节点操作Dom属性和方法(转)

    JavaScript 节点操作Dom属性和方法   一些常用的dom属性和方法,列出来作为手册用. 属性:   1.Attributes 存储节点的属性列表(只读)   2.childNodes 存储 ...

  3. JavaScript处理HTML DOM

    本来只想好好写一篇博文,最后弄到好像重构一样了,越做越不满意,先这样吧:) HTML DOM - JavaScript处理HTML DOM 获取HTML元素 改变HTML元素 增删HTML元素 添加事 ...

  4. javascript系列之DOM(一)

    原文:javascript系列之DOM(一) DOM(document object moudle),文档对象模型.它是一个中立于语言的应用程序接口(API),允许程序访问并修改文档的结构,内容和样式 ...

  5. javascript系列之DOM(二)

    原文:javascript系列之DOM(二) 原生DOM扩展 我们接着第一部分来说,上文提到了两种常规的DOM操作:创建文档片段和遍历元素节点.我们知道那些雨后春笋般的库,有很大一部分工作就是提供了一 ...

  6. javascript系列之DOM(三)---事件

    原文:javascript系列之DOM(三)---事件 事件是javascript跳动的心脏,是DOM所有成分结合的万金油.当我们在WEB 上进行某些交互时,事件也就发生了.点击某些内容,鼠标经过特定 ...

  7. JQuery $ $.extend(),$.fn和$.fn.extend javaScript对象、DOM对象和jQuery对象及转换 工具方法(utility)

    一.为什么jquery前面要写$ Javascript没有package的概念,而作者又希望所有jQuery相关的API都能通过一个全局性的对象来容纳. 名为jQuery的全局变量就是这样一个对象,不 ...

  8. javascript中获取dom元素的高度和宽度

    javascript中获取dom元素高度和宽度的方法如下: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网 ...

  9. JavaScript和HTML DOM的区别与联系

    JavaScript和HTML DOM的区别与联系 区别: javascript JavaScript 是因特网上最流行的浏览器脚本语言.很容易使用!你一定会喜欢它的! JavaScript 被数百万 ...

  10. console.time 简单分析javascript动态加入Dom节点的性能

    Bullshit 本来想每天都更新下博客的,可是近期要考试,还有就是自己还是停留在暗自窃喜中吧(这样的想法要改变). 事实上近期总在想.自己要怎么去管理自己的数据,每天的生活都是对自己的数据的增删查改 ...

随机推荐

  1. linux下查看进程占用端口和端口占用进程命令

    Linux下查看进程占用端口: 查看程序对应进程号:ps –ef|grep 进程名 REDHAT :查看进程号所占用的端口号:netstat –nltp|grep 进程号 ubuntu:查看进程占用端 ...

  2. Hover.css:一组超实用的 CSS3 悬停效果和动画

    Hover.css 是一套基于 CSS3 的鼠标悬停效果和动画,这些可以非常轻松的被应用到按钮.LOGO 以及图片等元素.所有这些效果都是只需要单一的标签,必要的时候使用 before 和 after ...

  3. 《HelloGitHub月刊》第03期

    <HelloGithub>第03期 兴趣是最好的老师,而<HelloGitHub> 就是帮你找到兴趣! 因为我比较熟悉python语言,所以月刊中python语言的项目居多,个 ...

  4. 各种排序学习归纳总结(Java)

    排序总结 根据<数据结构与算法分析——Java语言描述><INTRODUCTION TO JAVA PROGRAMMING>.维基及各技术博客知识点来总结的.  如果刚入门学习 ...

  5. Android中动态更新ListView(转)

    在使用ListView时,会遇到当ListView列表滑动到最底端时,添加新的列表项的问题,本文通过代码演示如何动态的添加新的列表项到ListView中.实现步骤:调用ListView的setOnSc ...

  6. 如何用Ajax加载服务器的图片

    用Ajax请求服务器的图片,并显示在浏览器中 前言 一直在数据库里面存的都是图片在服务器的地址,然后再到浏览器中显示,但是发现两个问题 第一:为了安全起见,js是无法读取本地的图片的,不然你写一个js ...

  7. JVM的GC概述

    JVM的GC概述 GC即垃圾回收,是指jvm用于释放那些不再使用的对象所占用的内存.在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能. 有些垃圾收集专用于特殊的应用程序.比如,实时应用程序 ...

  8. c#实现分组服务器,单一无重复生成ID

    class Program { static void Main(string[] args) { List<Thread> threads = new List<Thread> ...

  9. Swift 3.0首个开发者预览版将在5月12日释出

    Swift团队在博客中宣布Swift 3.0语言首个开发者预览版将于5月12日释出,正式版将在4-6周之后推出.开发者预览阶段并无确定的更新周期和计划,不过Swift团队称努力将其控 制在4-6周内. ...

  10. 从.net转型,聊聊最近一些面试,薪资和想法

    上一个星期,一篇名为<.net估计要写在你手里了>几乎点燃了整个园子,有人群情激愤了,有人点赞的,有人上去打算喷博主个体无完肤的,总之,这篇博客很成功的引起一些.net 从业者的思考,也包 ...