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. 让 jQuery UI draggable 适配移动端

    背景: 在移动端,本人要实现对某个元素的拖动,想到使用 jQuery UI 的 draggable 功能.但是发现此插件的拖动只支持PC端,不支持移动端. 原因: 原始的 jQuery UI 里,都是 ...

  2. Vue2.0流式渲染中文乱码问题

    在参照vue2.0中文官方文档学习服务端渲染之流式渲染时,因为响应头默认编码类型为GBK,而文件为UFT-8类型,所以出现了中文乱码问题. 解决办法:设置响应头编码类型即可 response.setH ...

  3. C语言学习016:单链表

    #include <stdio.h> //定义一个链表,链表是一种递归结构,在定义的时候必须要给结构起一个名字 typedef struct folder{ int level; char ...

  4. max server memory

    MS SQL Server 2008 R2,主要是用作ERP的数据库,但它的内存使用率非常高: 经查资料,原来数据库有默认的情况之下,使用内存时它是尽可能使用完有效内存.如果你不想这样,你可以手动分配 ...

  5. 【Java每日一题】20161121

    package Nov2016.use01; class Test { public String getString(){ return "123"; } } package N ...

  6. Maximum length of a table name in MySQL

    http://dev.mysql.com/doc/refman/5.7/en/identifiers.html The following table describes the maximum le ...

  7. XE7 iOS 取得系统字型名称

    系统字型名称在每个平台的取得方式不尽相同,以下示范如何在 iOS 取得系统内所有字型的名称: uses // 加入下面二个 uses 文件 iOSapi.UIKit, iOSapi.Foundatio ...

  8. SOA (面向服务的体系结构)

    面向服务的体系结构是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来.接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台.操作系统和编程语言 ...

  9. 简单理解——面向切面编程(AOP)

    在传统的编写业务逻辑处理代码时,我们通常会习惯性地做几件事情:日志记录.事务控制及权限控制等,然后才是编写核心的业务逻辑处理代码.当代码编写完成回头再看时,不禁发现,扬扬洒洒上百行代码中,真正用于核心 ...

  10. Verilog学习笔记简单功能实现(七)...............接口设计(并行输入串行输出)

    利用状态机实现比较复杂的接口设计: 这是一个将并行数据转换为串行输出的变换器,利用双向总线输出.这是由EEPROM读写器的缩减得到的,首先对I2C总线特征介绍: I2C总线(inter integra ...