js Dom

1. window对象作为全局对象,也就是说你可以通过window来访问全局对象。

  1.  属性在对象下面以变量的形式存放,在页面上创建的所有全局对象都会变成window对象的属性。
  2. 方法在对象下面以函数的形式存放,因为左右的函数都存放在window对象下面,所以他们也可以称为方法。

2. DOM为web文档创建带有层级的结果,这些层级是通过node节点组成,这里有几种DOM node类型,最重要的是Element, Text, Document。

  1.  Element节点在页面里展示的是一个元素,所以如果你有段落元素(<p>),你可以通过这个DOM节点来访问。
  2.  Text节点在页面里展示的所有文本相关的元素,所以如果你的段落有文本在里面的话,你可以直接通过DOM的Text节点来访问这个文本
  3.  Document节点代表是整个文档,它是DOM的根节点。

3. 每个引擎对DOM标准的实现有一些轻微的不同。例如,Firefox浏览器使用的Gecko引擎有着很好的实现(尽管没有完全遵守W3C规范),但IE浏览器使用的Trident引擎的实现却不完整而且还有bug,给开发人言带来了很多问题。

js Dom
(function () {
    // 这里自调用函数
})();
js Dom

Object

一个对象是一个key-value的集合,和数组相似,唯一的不同是你可以为每个数据定义一个名称。

js Dom
// 2种类型定义Object对象

// 字面量(大括号)
var profile = {
    name: ‘Bob‘,
    age: 99,
    job: ‘Freelance Hitman‘
};

// 使用Object构造函数
var profile = new Object();
profile.name = ‘Bob‘;
profile.age = 99;
profile.job = ‘Freelance Hitman‘;  
js Dom

getElementsByTagName

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

js Dom
// 访问无序列表: [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);
} 
js Dom

所有的节点都有这些属性,都是可以用于访问相关的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节点

属性可以像数组一样访问

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

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

很多元素的属性都是只读的,也就是说不能修改他们的值。例如,你不能直接修改一个节点的parentNode属性,如果你修改只读属性的时候浏览器会抛出错误:例如,抛出错误“setting a property that has only a getter”。

创建元素可以通过createElement方法,而创建text节点可以使用createTextNode。

js 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);
js Dom

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

js Dom
// ‘Target‘是DOM里已经存在的元素
// ‘Bullet‘是要插入的新元素
  
function insertAfter(target, bullet) {  
    target.nextSibling ?  
        target.parentNode.insertBefore(bullet, target.nextSibling)  
        : target.parentNode.appendChild(bullet);  
}  
  
// 使用了3目表达式:  
// 格式:条件?条件为true时的表达式:条件为false时的表达式
js Dom

鼠标事件

  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删除所有内容的时候触发该事件(例如离开一个页面)。

关于W3C和微软模型还有其他的少许差异,比如this,在触发事件的时候函数中的this一般都是该元素上下文,,也就说this引用该元素自身,在基本事件注册和W3C模型中都没有问题,但在微软模型的实现里却可能出错,请参考如下代码:

js Dom
function myEventHandler() {
    this.style.display = ‘none‘;
}
// 正常工作,this是代表该元素
myIntro.onclick = myEventHandler;
// 正常工作,this是代表该元素
myIntro.addEventListener(‘click‘, myEventHandler, false);
// 不正常,这时候的this是代表Window对象
myIntro.attachEvent(‘onclick‘, myEventHandler);
js Dom

这里有一些方式可以避免这个问题,最简单的方式是使用前面的基本事件注册方式,或者是再做一个通用的addEvent。

Event对象,当事件发生的时候出发某个函数,该Event对象将自动在函数内可用,该对象包含了很多事件触发时候的信息,但IE却没有这么实现,而是 自己实现的,IE浏览器是通过全局对象window下的event属性来包含这些信息,虽然不是大问题,但我们也需要注意一下,下面的代码是兼容性的:

js Dom
function myEventHandler(e) {
    e = e || window.event;
    // IE浏览器是通过全局对象window下的event属性来包含这些信息 
    /*防止默认行为:Event对象下的命令和属性都很有用,遗憾的是不不能全兼容浏览器,例如当你想取消默认的行为的时候你可以使用Event对象里的preventDefault()方法,
但IE里不得不使用对象的returnValue属性值来控制
*/ if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }
js Dom

停止冒泡

js Dom
function myParagraphEventHandler(e) {
    e = e || window.event;
    // 停止向上冒泡
    if (e.stopPropagation) {
        // W3C实现  
        e.stopPropagation();
    } else {
        // IE实现  
        e.cancelBubble = true;
    }
}
// 使用我们自定义的addEvent函数将myParagraphEventHandler绑定到click事件上:  
addEvent(document.getElementsByTagName(‘p‘)[0], ‘click‘, myParagraphEventHandler);
js Dom

事件委托

js Dom
var myTable = document.getElementById(‘my-table‘);
myTable.onclick = function () {
    // 处理浏览器兼容
    e = e || window.event;
    var targetNode = e.target || e.srcElement;
    // 测试如果点击的是TR就触发
    if (targetNode.nodeName.toLowerCase() === ‘tr‘) {
        alert(‘You clicked a table row!‘);
    }
}
js Dom

js Dom,布布扣,bubuko.com

js Dom

上一篇:如何编写高质量的 jQuery 代码?


下一篇:js 捕获浏览器关闭或者刷新页面给出提示