原生js获取dom元素-兼容写法
2016-03-05 16:42

    目前前端使用最多的js框架就是jQuery。他很好了封装了浏览器的兼容性,提供了简便链式的dom操作方法。对于我们实现效果非常方便。

    但是虽然有了jQuery我们还是有必要要了解下原生js的写法。鉴于移动端的发展,jQuery库的大小貌似有些过大。

    这里我们就探讨一下原生js的dom元素操作方式,(我下载的是最新的chrome和火狐浏览器)

    首先我们根据ID得到一个dom元素

    

var elem=document.getElementById("ele");

    1、得到elem的父元素。

var pt=elem.parentNode;//所有浏览器都兼容
var pt=elem.parentElement;//所有浏览器都兼容。
var pt=elem.parentElement||parentNode;//兼容写法。

  得到父元素的两种规范方式目前是都兼容,parentElement原是有IE提供的方式,后来各主流浏览器也跟着实现了此方法。所以如果要考虑较低版本的狐火和chrome浏览器的兼容时,可采用上面的兼容写法。

 2、得到elem的子元素。

var ch=elem.children;//所有浏览器都兼容,长度为3,加上注释后IE8及以下为4,既是包含comment注释元素
var ch=elem.childNodes;//IE8及以下长度为3,其他长度为7,包含文本节点
var ch=elem.chidren||chidNodes;//兼容写法

得到子元素的方法chidren是所有浏览器都兼容的,除却IE8以下会包含注释元素.而childNodes方法得到的子节点包含文本节点。需要用for循环判断nodeType是否为1来剔除非元素节点.nodeType类型可参看nodeType类型详解

而children属性是由IE最早实现,其他浏览器模仿实现。而且children不包含文本节点,符合我们大多数场景下的应用,所以兼容写法把chidren放到前面。

3、得到elem的上一个元素和下一个元素

var sib=elem.previousSibling;
var next=elem.nextSibling;//都支持,但是IE9+浏览器包括空文本,IE8及以下不包含空文本。
var sib=elem.previousElementSibling;
var next=elem.nextElementSibling;//IE8及以下不支持,其他浏览器支持且不包含空文本。
var sib=elem.previousElementSibling||elem.previousSibling;
var next=elem.nextElementSibling||elem.nextSibling;//兼容写法。


得到相邻元素的原生js同样有空文本节点的困扰。而previousSibling和nexSibling虽然都支持,但只有在IE8-的浏览器才不包含空文本节点,符合我们的预期。而nextElementSibling和previousElementSibling虽然不包含空文本节点且还是标准,不过IE8-浏览器不支持。所以我们可以采用如上的兼容写法。一定是previousElementSibling和nextElementSibling在前面,才能保证所有浏览器都能得到不含空文本节点的相邻元素。顺序不能颠倒的。

4、得到子元素的个数

var chlength=elem.childElementCount;//IE9+支持。
var chlength=elem.childElementCount||elem.children.length;//兼容写法。IE8及以下不能包含comment元素。

这个childElementCount算是新的dom方法,所以只有IE9+才支持,而他的效果跟children.length是一样一样的。这个兼容写法顺序也是不能改变的,因为IE9+浏览器支持childElementCount属性可以得到,而低版本的火狐和chrome不支持elem.children所以执行前一个操作不会走到elem.children为null而报错。而IE8-浏览器肯定会支持elem.chidren属性。

5、得到第一个子元素和最后一个子元素

var first=elem.firstChild;
var last=elem.lastChild;//都支持,IE9+包含空文本
var first=elem.firstElementChild;
var last=elem.lastElementChild;//IE9+支持,且不包含空文本。
var first=elem.firstElementChild||elem.firstChild;
var last=elem.lastElementChild||elem.lastChild;//兼容写法。

这个类似children和childNodes。IE9+的浏览器虽然也支持firstChild和lastChild,但是他们包含空文本节点,这个不是我们想要的。

而新的属性firstElementChild和lastElementChild在IE9+浏览器不包含空文本节点。所以就有了我们的兼容写法,注意:一定是firstElementChild和lastElementChild在前面,顺序不能改变,原理同之上的属性操作。

6、tagName和nodeName

var name=elem.tagName;//所有浏览器都支持
var name=elem.nodeName;//所有浏览器都支持。
var name=elem.firstChild.tagName;//ie9+为空文本,tagName为undifined
var name=elem.firstChild.nodeName;//IE9+的空文本,nodeName为#text。


在去除空文本元素的情况下,tagName和nodeName作用是相同的,都会返回标签的名称。而如果节点是飞元素节点时,譬如空文本,这时tagName

会返回undefined.而nodeName会返回#text。这个知识点只作为要操作文本节点的特殊场景的使用,如果不是特殊场景可以不关注他。

7、innerText和textContent

var element=elem.textContent;//IE9+为元素内的文本。
var element=elem.innerText;//FF不支持innerText;其他浏览器支持,并且会格式化。
var element=elem.innerText||elem.textContent//兼容写法;


这个我们大家所熟悉的是innerText,这个属性挺好使的,他可以过滤元素内的标签而得到文本内容。但是FF貌似不服,坚决不支持innerText而是有自己的textContent,不过这个textContent将标签转换成了文本缩进了。不过我们是web页面,大家都知道你写两个空格,浏览器会帮你合并成一个空格,所以尽管textContent带有缩进格式,但我们把他赋给dom元素内时,也不得不乖乖的把缩进给剔除了。兼容写法可以改变前后的顺序。

8、得到elem的class属性

var classn=elem.className;//都兼容
var classn=elem.getAttribute("class");//IE7为null,其他兼容
var classn=elem.getAttribute("className");//IE7兼容,其他为null
var classn=elem.classList.toString();//ie11以上支持,不建议现在使用。
var classn=elem.getAttribute("class")||elem.getAttribute("className");//兼容写法。
var claassn=elem.className||elem.getAttribute("class");


className属性是所有浏览器都支持的,返回的是class的字符串,而不保证低版本的火狐会支持。所以兼容写法可以采用getAttribute方法获得,而此方法时,IE7-是需要className作为参数的,其他浏览器是用class作为参数的。至于classList是H5的心属性,对IE来说是IE11才支持,其他浏览器也是较新版本才支持,不建议使用,如果你是移动端的webkit浏览器当然可以放心使用。不过其效率据说还没有className快呢。

9、elem.id和elem.getAttribute("id")

var attr=elem.getAttribute("dataname");//所有浏览器都支持
var attr=elem.dataname;//IE8-支持点操作自定义属性。
var attr=elem.id;//所有浏览器都支持。
var attr=elem['dataname'];//IE8-浏览器支持。
var attr=elem['dataname']||elem.getAttribute("dataname");//兼容写法


对于自定义属性IE8-支持点操作或者数组属性操作,所有浏览器都支持getAttribute方法操作。而对于非自定义属性,这两种方法所有浏览器都支持。所以这个兼容方式可以统一都采用getAttribute方法,活着如上的兼容写法。setAttribute兼容性与此类似。

10、document.all集合获取元素

var all=document.all;//所有浏览器都支持。
var it=all["sibling"];//ID获取元素,所有浏览器都支持。
var it=all["fc"]//name获取元素,所有浏览器都支持。
var iem=document.all.fmm;//all根据name获取form,所有浏览器都支持。
var iem=document.all.fmmid;//all根据id获取form,所有浏览器都支持。
var iem=document.all.nm;//all根据name获取非form元素,所有浏览器都支持。
var iem=document.all.my;//all根据ID获取非form元素,所有浏览器都支持。
//var iem=document.all.tags("div");//只有IE支持。
//var fm2=document.forms("fmmid");//id获取form只有IE支持。其他浏览器报错
//var fm2=document.forms("fmm");//name获取form只有IE支持。其他浏览器报错。
var fm2=document.forms["fmmid"];//数组属性Id获取form,所有浏览器都支持。
var fm2=document.forms["fmm"];//数组属性name获取form,所有浏览器都支持。
var fm2=document.forms.fmmid;//点操作ID获取form,所有浏览器都支持。
var fm2=document.forms.fmm;//点操作name获取form,所有浏览器都支持。
var fm2=document.forms[0];//下标操作获取form,所有浏览器都支持。
var fm2=document.forms.item(0);//item方法获取form,所有浏览器都支持。
//var fm2=document.forms.item(0).tags("input")[0].id;//仅IE支持,其他浏览器报错。
var fm2=document.fmm;//name获取form,所有浏览器都支持。
var fm2=document.fmmid;//ID获取form,只有IE支持。
//var iem=document.nm;//name获取非form元素,都不支持。
//var iem=document.my;//id获取非form元素,都不支持。
var fm=document.forms;//所有浏览器都支持。
var input=fm[0].my;//获取form中ID元素,所有浏览器都支持。
var input=fm[0].nm;//获取form中的name元素,所有浏览器都支持。
var div=elem.children.fc;//子元素点操作ID获取元素,所有浏览器都支持。(获取name都不支持)
var div=elem.children["fc"];//数组属性操作ID获取元素,所有浏览器都支持。
//var div=elem.children["aas"];//数组操作name获取元素,所有浏览器都不支持。
var div=elem.children.item(0);//所有浏览器都支持。
var div=elem.children[0];//所有浏览器都支持。
var script=document.scripts;//所有浏览器都支持。
var linkss=document.links;//所有浏览器都支持,获取所有带有href的a标签和area链接。
var as=document.anchors;//所有浏览器都支持,获取所有带有name和/或ID的A标签
var style=document.styleSheets.length;//获取样式文件元素。所有浏览器都支持。
var namespace=document.namespaces;//获取命名空间,IE9-支持
var imgs=document.images;//获取所有img对象所有浏览器都支持。
var frame=document.frames;//只有IE支持。
var emb=document.embeds;//获取文档中所有 embed 对象的集合。所有浏览器都支持。


虽然document.all和document.forms,document.images,document.embeds等最早有IE支持,但目前所有主流浏览器都支持对dom元素进行集合操作。但是其他浏览器没有生成自己对其支持,也就是说可能下一个版本对其不支持。从上面的兼容性测试,可以看出,所有浏览器都支持的对集合操作的方法是是通过数组,或者item方法,点操作ID。

这些个集合操作dom元素的方法虽然都兼容,但是不建议使用,还是用getElementById,getElementsByTagName的方法来获取元素靠谱些。这里只是让大家对集合操作有所理解,日后看到此类写法也不至于抓狂,知道是什么意思即可。


总结:本文归纳了原生js得到相关dom元素的兼容写法。测试浏览器乃最新版本,如有不正确的地方还望指正。接下来的几篇文章,我将归纳更多的原生js的写法,敬请关注。





原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(3093)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1