javascript --- javascript与DOM

javascript与DOM

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

<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段落。java

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

变量pDom如今已经引用到该DOM节点上了,咱们能够对该节点作不少事情,好比查询内容和属性,或者其它任何操做,甚至能够删除它,克隆它,或者将它移到到DOM树的其它节点上。node

文档上的任何内容,咱们均可以使用JavaScript和DOM API来访问,因此相似地,咱们也能够访问上面的无序列表,惟一的问题是该元素没有ID属性,若是ID的话就可使用相同的方式,或者使用以下getElementsByTagName方式:web

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提供了大量的节点属性让咱们来往上或者往下查询节点。app

全部的节点都有这些属性,都是能够用于访问相关的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类型能够经过此地址google

    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来改变该元素的颜色:spa

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删除全部内容的时候触发该事件(例如离开一个页面)。
相关文章
相关标签/搜索