Go to comments

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才是真正代表整个文档

image.png

了解到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 选出来也是一组



Leave a comment 0 Comments.

Leave a Reply

换一张