JavaScript DOM选择器(查看元素)
查看元素节点
document | 代表整个文档 | |
.getElementById() | 元素id | 在Ie8以下的浏览器,不区分id大小写,而且也返回匹配name属性的元素 |
.getElementsByTagName() | 标签名 | |
.getElementsByName() | 只有部分标签name可生效(表单,表单元素,img,iframe) | IE不支持需注意 |
.getElementsByClassName() | 类名,可以多个class一起 | ie8和ie8以下的ie版本中没有 |
.querySelector() | css选择器 | 在ie7和ie7以下的版本中没有 |
.querySelectorAll() | css选择器 | 在ie7和ie7以下的版本中没有 |
DOM是一系列方法的集合,用来操作HTML和XML的(不操作CSS),DOM没法直接操作CSS,它对CSS的修改和查看全是间接的,
学习DOM还是按照增、删、改、查的顺序,这节课学习查看元素有什么方法和特性,在学习DOM之前先了解一下document
1、 document 代表整个文档
document是一个对象,它上面有一些属性和方法,但是这不是重点,要知道document代表的是什么东西,单独写document它代表的是整个文档的js显示形式。
比如,写一个div元素,如果通过一个方法把这个div选出来,就是把这个div选到js里面可以用js去操作了
<div></div> <script> var oDiv = document.getElementsByTagName('div')[0]; </script>
oDiv是div在js里面的一个展现形式,如果整个文档也能用js来表示,那就只能用document来展示
整个文档是什么意思呢?
现在我们理解整个文档的最顶级是HTML标签,HTML标签基本代表了整个文档,
如果给HTML标签上面再套一层标签,这个标签肯定是document,也就是说document它真正代表的是整个文档,而HTML只是文档里面的根标签,
换句话说HTML是最核心最主要的部分,但HTML还不能代表整个文档,也就是说HTML代码上面肯定还有标签,只是没有在代码上显示。
在控制台输入doucment回车,把鼠标放到 #doucment 上,会发现整个文档都变色了,document才是真正代表整个文档
了解到document代表整个文档就可以了,然后document上还具备很多的方法,接下来全是查看这些标签、元素的方法
2、 getElementById()
比如div写到页面里面了,js要想操作div就先找到它
第一个方法,在document上有一个方法getElementById(),通过ID标识选择元素,ID和元素之间是一一对应的唯一标识,所以通过ID选择元素是一个不是一组
<div id="only">only</div> <script> var Div = document.getElementById('only'); console.log(Div);// <div id="only">only</div> </script>
第一个方法有几个小的注意点
1. 在IE8以下的浏览器,ID是不区分大小写(大写小写代表的是一个)在IE9以上就不是了
2. 在IE8以下的浏览器(IE7, IE6)如果这个元素没有ID,它的name值等于"only"也能被选出来,现在是选不出来了
// <div nmae="only">only</div> // 在IE8以下的浏览器(IE7,IE6)元素没有ID,它的name值等于"only"也能被选出来 // var Div = document.getElementById('only');
3、 getElementsByTagName()
第二个方法getElementsByTagName(),TagName是标签名字的意思,通过标签名的方式来选择
<div>div</div> <script> var oDiv = document.getElementsByTagName('div'); console.log(oDiv); // HTMLCollection [div] </script>
document.getElementsByTagName('div') 这句话的意思是
1. 把页面里所有的DIV元素都选出来,选出来的DIV肯定是一组,即使只有一个也得成一个数组来展示,
2. 然而返回的 HTMLCollection [div] 并不是数组,如果是数组会有数组的一些方法,数组的push方法肯定能用
<div>div</div> <script> var oDiv = document.getElementsByTagName('div'); oDiv.push(1); // Uncaught TypeError: oDiv.push is not a function </script>
报错 oDiv.push is not a function 说明它是类数组(类数组,既能当数组使又能当对象使,把它俩的好处结合到一起了)
记住,从DOM开始包括BOM以后的一系列的东西,一切系统给生成的成组的方式,基本上全是类数组。
所以取这个div操作要加一个[0]
<div>div</div> <script> var oDiv = document.getElementsByTagName('div')[0]; console.log(oDiv); // <div>div</div> </script>
现在这个oDiv代表一个div元素了,可以给div元素添加样式
<div>div</div> <script> var oDiv = document.getElementsByTagName('div')[0]; oDiv.style.background = "red"; // 默认返回red(控制台上) // <div style="background: red;">div</div> </script>
但是不加[0],这个oDiv代表的一个数组,数组要加样式报错
<div>div</div> <script> var oDiv = document.getElementsByTagName('div'); oDiv.style.background = "red"; // Uncaught TypeError: Cannot set property 'background' of undefined </script>
getElementsByTagName()方法非常常用一定要记住,它的兼容性特别好IE4都能用,在任何浏览器上都可以正常使用而且是最主流的用法
在css里面提倡用class选择器,能用class就不用ID选择器,但是在js里面class选择器确实也挺常用的,可是没有那么常用,为什么呢?
有一个方法是getElementsByClassName()这个方法好用是好用,但是它有一个问题!
4、 getElementsByClassName()
getElementsByClassName()方法选出来的也是一组,因为class是多对多的关系
<div class="demo">demo</div> <script> var oDiv = document.getElementsByClassName('demo')[0]; // 写一个[0],div元素也选出来了 console.log(oDiv); // <div class="demo">demo</div> </script>
但是有个问题,
getElementsByClassName方法并不是所以浏览器都兼容,通过class类名来选择元素,在IE8和IE8以下的浏览器里面根本就没有这个方法,
也就是说IE9以下浏览器是没有getElementsByClassName方法,正是因为这样没有getElementsByTagName方法更常用更灵活,所以真正用的频率高的是getElementsByTagName方法。
5、 getElementsByName()
getElementsByName()方法可以通过name的方式选择元素,但是要记住一点这个方法不是很常用,
有些标签写成name的方式,可以通过name的方式去选择,比如Input元素里面有name,输入框里的name代表数据名
<input name="fruit"/> <script> var inp = document.getElementsByName('fruit')[0]; console.log(inp); // <input name="fruit"> </script>
它选出来的也是一组数据,除了ID选择器任何一个选择元素方法,选出来的都是一组
有一个问题:
这个name属性在新版本的浏览器虽然也都能用,但是往前在推几个浏览器版本,这个name属性并不是在所有标签上都好使,
因为要知道name属性是有自己根本含义的,它根本的含义是能提交数据组件的数据名,它表示的是数据名,否则加name没有任何的意义,
所以理论上只有部分标签name才可以生效,
比如表单(form)表单元素各种input元素、img也可以提交因为它可以发送数据请求、iframe官方标准里也可以加name属性的标签
其它的标签给比如div加name没什么用,但现在浏览器更新版本比较高,给div加上name也能识别出来,但是在之前的浏览器里面给div、p标签加name是没有意义的,因为这是W3C官方的语法规定。
getElementsByName()方法知道就行了开发的时候没人用,因为完全可以用Class、Id、标签名来代替
6、做几个小例子
怎么把div都选出来?
<div></div> <div></div> <div></div> <p></p> <script> var div = document.getElementsByTagName('div'); // 把一组的div都选出来了 console.log(div.length); // 这个组还有length属性,可以循环遍历它(div.length返回2) div[1].innerHTML = 123; // div[1]代表第二个元素可以操作它,比如给里面加内容123 </script>
选div里面的p标签怎么写?
<div> <p>1</p> </div> <p>2</p> <script> var p = document.getElementsByTagName('p')[0]; // 选出的是两个p,放第一个[0]就完事了 console.log(p); // <p>1</p> </script>
如果给第一个p元素加一个 class="demo" ,选择它用什么选择器方便点?
<div> <p class="demo">1</p> </div> <p>2</p> <script> var p = document.getElementsByClassName('demo')[0]; // 注意,尽管页面里只有一个class="demo"的元素,但选出来的仍然是一组,要想选出特定的一个必须要加下角标[0] console.log(p); // <p class="demo">1</p> </script>
下面还有两个选择器特别厉害
第一个 querySelector(),
第二个 querySelectorAll()
7、 querySelector()
querySelector()方法也是document上的方法
正常来说想要选(下面代码中)第二个srtong,1.要都选出来 2.然后查数第二个[1],但querySelector()就不需要了,css里怎么选这个strong在这里就可以怎么选
<div> <strong>1</strong> </div> <div> <span> <strong>2</strong> <span> </div> <script> var strong = document.querySelector('div > span > strong'); // CSS怎么写,querySelector这里就怎么写 console.log(strong); // <strong>2</strong> </script>
给第二个strong标签加一个 class="dome" 属性,然后用并列选择器选择strong
<div> <strong>1</strong> </div> <div> <span> <strong class="demo">2</strong> <span> </div> <script> var strong = document.querySelector('div > span strong.demo'); // 并列选择器这么复杂也完全没问题,querySelector识别的就是css console.log(strong); // <strong class="demo">2</strong> </script>
而且querySelector()方法选出来的是一个,不是一组,与它相对应的同样里面可以写css选择器的是querySelectorAll()方法
8、 querySelectorAll()
尽管querySelectorAll()里面写的是css选择器,但是它选出来的是一组
<div> <strong>1</strong> </div> <div> <span> <strong class="demo">2</strong> <span> </div> <script> var strong = document.querySelectorAll('div > span strong.demo'); console.log(strong); // NodeList [strong.demo] </script>
9、querySelector() 和 querySelectorAll() 的区别
比较一下querySelector() 和 querySelectorAll() 它俩的区别
querySelector() 选出来的是一个元素 <strong class="demo">2</strong>
querySelectorAll() 出来的是一个数组,里面放一个 NodeList [strong.demo]
<div> <strong>1</strong> </div> <div> <span> <strong class="demo">2</strong> <span> </div> <script> var strong = document.querySelector('div > span strong.demo'); var strong1 = document.querySelectorAll('div > span strong.demo'); console.log(strong); // <strong class="demo">2</strong> console.log(strong1); // NodeList [strong.demo] </script>
综合起来看是get的方便还是query的方便?
query的方便因为写的是css选择器,然而query方法并不使用,为什么现实总这么残酷,这么好的方法不用?
querySelector() 和 querySelectorAll() 选出来的元素不是实时的
1. 确实在IE6、IE7上并没有query方法,但是老版本IE现在不用了,也就是说这个缺点对我们没什么影响
2. 第二个缺点要命了是实时性的问题,querySelector 和 querySelectorAll选出来的元素不是实时
不是实时的是什么意思,举一个例子
1、先看实时的例子
<div></div> <div class="demo"></div> <div></div> <script> var oDiv= document.getElementsByTagName('div'); // 现在要把三个div全选出来 console.log(oDiv); // HTMLCollection(3) [div, div.demo, div] var demo = document.getElementsByClassName('demo')[0]; // 然后单独把第二个div选出来 console.log(demo); // <div class="demo"></div> demo.remove(); // 现在看什么是"实时"的,把第二个干掉,第二个div就消失了 console.log(oDiv); // HTMLCollection(2) [div, div] 第二个div消失了之后这个组里div剩下两个了,它是实时根据修改的更改 </script>
div.remove把第二个div干掉,第二个div消失了之后,这个组里面的div剩下两个了,oDiv实时的根据修改的更改
下面在js里创建一个新div,插入到页面里面去,也是实时更新的
<div></div> <div class="demo"></div> <div></div> <script> var oDiv= document.getElementsByTagName('div'); // 现在要把三个div全选出来 var newDiv = document.createElement('div'); // 在js里创建一个新的div标签 document.body.appendChild(newDiv); // 把这个新标签放到页面里面 console.log(oDiv); // HTMLCollection(4) [div, div.demo, div, div] </script>
选div元素是在创建新div之前,再查看时有四个div元素了,这个就是实时的
2、不是实时的例子
然后querySelectoarAll()可能让我们失望了,它选出来是静态的是副本
querySelectoarAll()一开始也选出来三个div,自此之后它选出的这三个div就是这三个div的一个副本了,换句话说其它的在怎么修改跟它原来这个组就没关系了
<div></div> <div class="demo"></div> <div></div> <script> var oDiv = document.querySelectorAll('div'); // 现在选出三个div var demo = document.getElementsByClassName('demo')[0]; demo.remove(); // 然后把第二个div干掉 console.log(oDiv); // NodeList(3) [div, div.demo, div],再看还是那三个div,跟删除操作没关系,它是静态的 </script>
因为querySelector和querySelectorAll不是实时的,所以在用法上极其的受局限,除非在极特殊的情况下,就想选它的副本保存起来否则的话我们不用
querySelectorAll正常操作是可以的,但是就特殊在不是实时的
<div></div> <div class="demo"></div> <div></div> <script> var oDiv = document.querySelectorAll('div'); // 一下子选中三个div元素 oDiv[0].style.background = 'red'; oDiv[0].style.color = '#fff'; oDiv[0].innerHTML = 123; </script>
这是选择元素方法类的操作,还有一些选择元素非方法类的操作节点树
节点树
选择元素未必非得方法,比如选择你旁边那个人,这也就把人选出来了,通过一个目标它的周边的环境也能选,因为它们和周边都有联系,
接下来的方法是基于一个元素,它周边辐射性的东西能选出元素来,这是一种关系类的选择,关系类的选择也有语法叫"节点树",把关系梳理成一个数形结构。
总结
1. document是一个对象代表整个文档,它上还具备很多"查看"标签/元素的方法。
2. getElementById() 只能选一个
3. 下面三个get选择器选出来的都是类数组,不能用数组的方法否则会报错
getElementsByTagName() 兼容想非常好,用的也非常多
getElementsByName() 有语法含义,规范上只能在一些标签上可以用
getElementsByClassName() IE8及以下浏览器不兼容,后面收尾课程里面会重写一个这样的兼容性方法
4. 下面两个query选择器可以像css选择器那样选择元素,但是致命的缺点选出来的元素不是事实时
querySelector 选出来的是一个
querySelectorAll 选出来也是一组