1. window对象作为全局对象,也就是说你可以通过window来访问全局对象。
2. DOM为web文档创建带有层级的结果,这些层级是通过node节点组成,这里有几种DOM node类型,最重要的是Element, Text, Document。
3. 每个引擎对DOM标准的实现有一些轻微的不同。例如,Firefox浏览器使用的Gecko引擎有着很好的实现(尽管没有完全遵守W3C规范),但IE浏览器使用的Trident引擎的实现却不完整而且还有bug,给开发人言带来了很多问题。
(function () { // 这里自调用函数 })();
一个对象是一个key-value的集合,和数组相似,唯一的不同是你可以为每个数据定义一个名称。
// 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‘;
getElementsByTagName方法返回的是一个节点集合,和数组类似也有length属性,重要的一个特性是他是live的——如果你 在该元素里添加一个新的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); }
所有的节点都有这些属性,都是可以用于访问相关的node节点:
有个非常重要的知识点:那就是元素之间不能有空格,如果ul和li之间有空格的话,就会被认为是内容为空的text node节点,这样ul.childNodes[0]就不是第一个li元素了。相应地,<p>的下一个节点也不是<ul>,因 为<p>和<ul>之间有一个空行的节点,一般遇到这种情况需要遍历所有的子节点然后判断nodeType类型,1是元素,2是 属性,3是text节点
属性可以像数组一样访问
function changeStyle(elem, property, val) { elem.style[property] = val; // 使用[]来访问属性 } // 使用上述的函数: var myIntro = document.getElementById(‘intro‘); // 获取intro文本对象 changeStyle(myIntro, ‘color‘, ‘red‘);
很多元素的属性都是只读的,也就是说不能修改他们的值。例如,你不能直接修改一个节点的parentNode属性,如果你修改只读属性的时候浏览器会抛出错误:例如,抛出错误“setting a property that has only a getter”。
创建元素可以通过createElement方法,而创建text节点可以使用createTextNode。
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时的表达式
关于W3C和微软模型还有其他的少许差异,比如this,在触发事件的时候函数中的this一般都是该元素上下文,,也就说this引用该元素自身,在基本事件注册和W3C模型中都没有问题,但在微软模型的实现里却可能出错,请参考如下代码:
function myEventHandler() { this.style.display = ‘none‘; } // 正常工作,this是代表该元素 myIntro.onclick = myEventHandler; // 正常工作,this是代表该元素 myIntro.addEventListener(‘click‘, myEventHandler, false); // 不正常,这时候的this是代表Window对象 myIntro.attachEvent(‘onclick‘, myEventHandler);
这里有一些方式可以避免这个问题,最简单的方式是使用前面的基本事件注册方式,或者是再做一个通用的addEvent。
Event对象,当事件发生的时候出发某个函数,该Event对象将自动在函数内可用,该对象包含了很多事件触发时候的信息,但IE却没有这么实现,而是 自己实现的,IE浏览器是通过全局对象window下的event属性来包含这些信息,虽然不是大问题,但我们也需要注意一下,下面的代码是兼容性的:
function myEventHandler(e) { e = e || window.event; // IE浏览器是通过全局对象window下的event属性来包含这些信息 /*防止默认行为:Event对象下的命令和属性都很有用,遗憾的是不不能全兼容浏览器,例如当你想取消默认的行为的时候你可以使用Event对象里的preventDefault()方法,
但IE里不得不使用对象的returnValue属性值来控制*/ if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }
停止冒泡
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);
事件委托
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!‘); } }
原文:http://www.cnblogs.com/Watcher/p/3605081.html