js
在操作DOM
中存在着许多跨浏览器方面的坑,本文花了我将近一周的时间整理,我将根据实例整理那些大大小小的“坑”。
DOM
的工作模式是:先加载文档的静态内容、再以动态方式对它们进行刷新,动态刷新不影响文档的静态内容。
PS:IE
中的所有 DOM
对象都是以 COM
对象的形式实现的,这意味着 IE
中的 DOM
可能会和其他浏览器有一定的差异。
Node 接口
特性/方法 | 类型/返回类型 | 说 明 |
---|---|---|
nodeName | String | 节点的名字;根据节点的类型而定义 |
nodeValue | String | 节点的值;根据节点的类型而定义 |
nodeType | Number | 节点的类型常量值之一 |
ownerDocument | Document | 返回某元素的根元素 |
firstChild | Node | 指向在childNodes列表中的第一个节点 |
lastChild | Node | 指向在childNodes列表中的最后一个节点 |
childNodes | NodeList | 所有子节点的列表 |
previousSibling | Node | 返回选定节点的上一个同级节点,若不存在,则返回null |
nextSibling | Node | 返回被选节点的下一个同级节点,若不存在,则返回null |
hasChildNodes() | Boolean | 如果当前元素节点拥有子节点,返回true,否则返回false |
attributes | NamedNodeMap | 返回包含被选节点属性的 NamedNodeMap |
appendChild(node) | node | 将node添加到childNodes的末尾 |
removeChild(node) | node | 从childNodes中删除node |
replaceChild(newnode, oldnode) | Node | 将childNodes中的oldnode替换成newnode |
insertBefore | Node | 在已有子节点之前插入新的子节点 |
firstChild
相当于 childNodes[0]
;lastChild
相当于childNodes[box.childNodes.length - 1]
。
nodeType返回结点的类型
1 2 3 |
--元素结点返回1 --属性结点返回2 --文本结点返回3 |
innerHTML 和 nodeValue
1 2 3 4 5 |
对于文本节点,nodeValue 属性包含文本。 对于属性节点,nodeValue 属性包含属性值。 nodeValue 属性对于文档节点和元素节点是不可用的。 |
两者区别
1 2 |
box.childNodes[0].nodeValue = '<strong>abc</strong>';//结果为:<strong>abc</strong> abcbox.innerHTML = '<strong>abc</strong>';//结果为:abc |
nodeName属性获得结点名称
1 2 3 |
--对于元素结点返回的是标记名称,如:<a herf><a>返回的是"a" --对于属性结点返回的是属性名称,如:class="test" 返回的是test --对于文本结点返回的是文本的内容 |
tagName
1 |
document.getElementByTagName(tagName):返回一个数组,包含对这些结点的引用 |
getElementsByTagName()
方法将返回一个对象数组 HTMLCollection(NodeList)
,这个数组保存着所有相同元素名的节点列表。
1 |
document.getElementsByTagName('*');//获取所有元素 |
PS:IE
浏览器在使用通配符的时候,会把文档最开始的 html
的规范声明当作第一个元素节点。
1 2 3 4 |
document.getElementsByTagName('li');//获取所有 li 元素,返回数组 document.getElementsByTagName('li')[0];//获取第一个 li 元素,HTMLLIElement document.getElementsByTagName('li').item(0);//获取第一个 li 元素,HTMLLIElement document.getElementsByTagName('li').length;//获取所有 li 元素的数目 |
节点的绝对引用:
1 2 3 4 5 |
返回文档的根节点:document.documentElement 返回当前文档中被击活的标签节点:document.activeElement 返回鼠标移出的源节点:event.fromElement 返回鼠标移入的源节点:event.toElement 返回激活事件的源节点:event.srcElement |
节点的相对引用:(设当前对节点为node)
1 2 3 4 5 6 7 8 |
返回父节点:node.parentNode || node.parentElement(IE) 返回子节点集合(包含文本节点及标签节点):node.childNodes 返回子标签节点集合:node.children 返回子文本节点集合:node.textNodes 返回第一个子节点:node.firstChild 返回最后一个子节点:node.lastChild 返回同属下一个节点:node.nextSibling 返回同属上一个节点:node.previousSibling |
节点信息
1 2 3 |
是否包含某节点:node.contains() 是否有子节点node.hasChildNodes() |
创建新节点
1 2 3 |
createDocumentFragment()--创建文档碎片节点 createElement(tagname)--创建标签名为tagname的元素 createTextNode(text)--创建包含文本text的文本节点 |
获取鼠标点击事件的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
document.onclick = mouseClick; function mouseClick(ev){ ev = ev || window.event;//window.event用来兼容IE var x = 0; var y = 0; if(ev.pageX){ x = ev.pageX; y = ev.pageY; }else if(ev.clientX){ var offsetX = 0 , offsetY = 0; if(document.documentElement.scrollLeft){ offsetX = document.documentElement.scrollLeft; offsetY = document.documentElement.scrollTop; }else if(document.body){ offsetX = document.body.scrollLeft; offsetY = document.body.scrollTop; } x = ev.clientX + offsetX; y = ev.clientY + offsetY; } alert("你点击的位置是 x="+ x + " y=" + y); } |
以下所描述的属性在chrome
和Safari
都很给力的支持了。
问题一:Firefox
,Chrome
、Safari
和IE9
都是通过非标准事件的pageX
和pageY
属性来获取web页面的鼠标位置的。pageX/Y
获取到的是触发点相对文档区域左上角距离,以页面为参考点,不随滑动条移动而变化
问题二:在IE 中,event
对象有 x
, y
属性(事件发生的位置的 x
坐标和 y
坐标)火狐中没有。在火狐中,与event.x
等效的是event.pageX
。event.clientX
与 event.pageX
有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
offsetX
:IE
特有,chrome
也支持。鼠标相比较于触发事件的元素的位置,以元素盒子模型的内容区域的左上角为参考点,如果有boder
,可能出现负值
问题三:
scrollTop
为滚动条向下移动的距离,所有浏览器都支持document.documentElement
。
其余参照:http://segmentfault.com/a/1190000002559158#articleHeader11
参照表
(+
为支持,-
为不支持):
1 2 3 4 5 6 7 8 9 10 11 |
offsetX/offsetY:W3C- IE+ Firefox- Opera+ Safari+ chrome+ x/y:W3C- IE+ Firefox- Opera+ Safari+ chrome+ layerX/layerY:W3C- IE- Firefox+ Opera- Safari+ chrome+ pageX/pageY:W3C- IE- Firefox+ Opera+ Safari+ chrome+ clientX/clientY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+ screenX/screenY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+ |
查看下方DEMO
:
你会发现offsetX
在Firefox
下是undefined
,在chrome
和IE
则会正常显示。
https://jsfiddle.net/f4am208m/embedded/result/