浅谈JS获取元素的N种方法及其动静态讨论

实际前端开发工作中,我们经常会遇到要获取某些元素,以达到更新该元素的样式、内容等目的。而文档对象模型 (DOM) 是HTML和XML文档的编程接口,它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合,它会将web页面和脚本或程序语言连接起来。也因此,JavaScript可以通过DOM API获取元素节点,方法有如下几种:其中querySelector()和querySelectorAll()为ES5的元素选择方法

1、getElementById():

接收一个参数:要取得的元素的ID(区分大小写,必须严格匹配),返回一个Element对象(也可看作是动态NodeList集合,只是集合中只包含一个匹配的元素,但也会实时反映DOM节点的变化),若当前文档中拥有特定ID的元素不存在则返回nul。
语法:

element = document.getElementById(id);

示例:删除

<body>
  <div id="myDiv">
    <p class="myP">hello world</p>
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>
  <script>
    var div = document.getElementById("myDiv");
    console.log(div); //(1)
    var body=document.querySelector('body');
    body.removeChild(div);
    console.log(body); //(2)
  </script>
</body>
//(1)处打印值
  <div id="myDiv">
    <p class="myP">hello world</p>
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>

//(2)处打印值
<body>
  <script>
    var div = document.getElementById("myDiv");
    console.log(div); //(1)
    var body=document.querySelector('body');
    body.removeChild(div);
    console.log(body); //(2)
  </script>
</body>

示例:

<!DOCTYPE html>
<html>
<head>
 <title>getElementById example</title>
 <script>
 function changeColor(newColor) {
  var elem = document.getElementById("para1");
  elem.style.color = newColor;
 }
 </script>
</head>
<body>
 <p id="para1">Some text here</p>
 <button onclick="changeColor('blue');">blue</button>
 <button onclick="changeColor('red');">red</button>
</body>
</html>

getElementById()方法不会搜索不在文档中的元素。当创建一个元素且分配ID后,必须要使用insertBefore()或其他类似的方法把元素插入到文档中之后才能使用 getElementById() 获取到:

var element = document.createElement("div");
element.id = 'testqq';
var el = document.getElementById('testqq'); // el will be null!

2、getElementsByClassName():

接收一个参数,即包含一个或多个类名的字符串(类名通过空格分隔),返回一个HTMLCollection动态集合(也可以说返回一个NodeList类数组对象),集合中包含以当前元素为根节点,所有指定 class 名的子元素。
语法:

var elements = document.getElementsByClassName(names);
var elements = rootElement.getElementsByClassName(names);

getElementsByClassName 可以在任意的元素上调用,不仅仅是document。 调用这个方法的元素将作为本次查找的根元素。

示例:

获取所有 class 为 'test' 的元素:

document.getElementsByClassName('test');

获取所有 class 同时包括 'red' 和 'test' 的元素:

document.getElementsByClassName('red test');

在id 为'main'的元素的子节点中,获取所有class为'test'的元素:

document.getElementById('main').getElementsByClassName('test');

示例:删除

//html代码
<div class="myDiv">
    <p class="myP">hello world</p>
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>
//js代码一
  <script>
    var div = document.getElementsByClassName("myDiv");
    console.log(div); //(3)
    var p = document.getElementsByClassName("myP");
    for (var i = 0; i < p.length; i++) {
      div[0].removeChild(p[i]);
    }
    console.log(p); //(4)
  </script>
//(3)处打印值
[div.myDiv] //一个动态的HTMLCollection集合,长度为1,innerHTML为<p class="myP">hello dolby</p>,<p class="myP">hello bean</p>,为什么没有其他两个p元素一会儿解释。

//(4)处打印值
[p.myP,p.myP] //一个动态的HTMLCollection集合,长度为2,innerHTML分别为"hello dolby","hello bean"。

以上用删除节点的方法验证了getElementsByClassName方法返回的是一个HTMLCollection动态集合。

⬆️以上代码中,首先div取得了页面中类名为"myDiv"的元素组成的动态集合,p取得了页面中类名为"myP"的元素组成的动态集合,接着用一个for循环来删除"myDiv"集合中第一项(即上例中唯一的div元素)中的"myP"集合中的每一项,结果只有第一项和第三项被删除了,这是为什么呢?

原因是动态集合中DOM结构的变化能够自动反映到所保存的对象中,最开始p.legth=4,当i=0时删除了页面中第一个p元素,此后p.length=3;i=1时删除了剩余的三个p中的项目索引为1的项,此后p.length=2;i=2时已不满足i<p.length这一条件,所以不会继续执行循环。至此只删除了页面上的第一和第三个p元素,所以打印p得到了一个长度为2的HTMLCollection动态集合,其中包含"hello dolby"和"hello bean",p的变化也实时反映到了动态集合div中,所以才有(1)处的打印结果。

那么怎样才能遍历类数组对象HTMLCollection集合中的每一项并且删除所有项呢?

还是一个for循环搞定⬇️,每次删除对象集合中的最后一项就可以啦~

//js代码二
  <script>
    var div = document.getElementsByClassName("myDiv")[0];
    console.log(div); //(5)
    var p = document.getElementsByClassName("myP");
    for (var i=p.length;i--;){
      div.removeChild(p[i]);
    }
    console.log(p); //(6)
  </script>
//(5)处打印值
<div class="myDiv"></div>

//(6)处打印值
[] //空的HTMLCollection集合,长度为0

3、getElementsByTagName():

接收一个参数:要取得的元素的标签名(不区分大小写),返回一个HTMLCollection动态集合(也可以说返回一个NodeList类数组对象),集合中包含以当前元素为根节点(不包括当前元素自身),所有指定标签名的子元素,子元素的顺序是在当前元素的子树中出现的顺序,如果没有搜索到元素则集合为空。
语法:

elements = element.getElementsByTagName(tagName)

示例:

// check the alignment on a number of cells in a table.
var table = document.getElementById("forecast-table");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
  var status = cells[i].getAttribute("data-status");
  if ( status == "open" ) {
    // grab the data
  }
}

示例:删除

<body>
  <div id="myDiv">
    <p class="myP">hello world</p>
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>
  <script>
    var div = document.getElementById("myDiv");
    console.log(div); //(7)
    var p = document.getElementsByTagName("p");
//以下for循环改为for (var i=0,len=p.length;i<len;i++) {div.removeChild(p[0]);}也可;将集合p的长度赋值给变量len,这样len就是一个固定值,每次都删除当前集合项目索引为0的项,就可以循环遍历删除掉集合里的所有项。
    for (var i=p.length;i--;){
      div.removeChild(p[i]);
    }
    console.log(p); //(8)
  </script>
</body>

与getElementByClassName相同,返回动态集合,所以循环删除结果也相同

//(7)处打印值
<div id="myDiv"></div>

//(8)处打印值
[] //空的HTMLCollection集合,长度为0

4、getElementsByName():

接收一个参数:带有给定name属性值的元素,返回一个动态NodeList类数组对象,对象中包含以当前元素为根节点,所有指定name属性值的子元素。最常用的场景是取得单选按钮。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
 ...
</head>

<body>
<form name="up"><input type="text"></form>
<div name="down"><input type="text"></div>

<script>
var up_forms = document.getElementsByName("up");
console.log(up_forms[0].tagName); // returns "FORM"
</script>
</body>
</html>

示例:删除

<body>
  <div id="myDiv">
    <input type="radio" name="fav-color">red
    <input type="radio" name="fav-color">green
    <input type="radio" name="fav-color">blue
  </div>
  <script>
    var div = document.getElementById("myDiv");
    console.log(div); //(9)
    var ipt_favCol = document.getElementsByName("fav-color");
    for (var i = ipt_favCol.length; i--;) {
      div.removeChild(ipt_favCol[i]);
    }
    console.log(ipt_favCol); //(10)
  </script>
</body>

getElementByName返回的是一个NodeList动态集合

//(9)处打印值
<div id="myDiv">
"red"
"green"
"blue"
</div>

//(10)处打印值
[] //空的NodeList集合,长度为0

5、querySelector():

接收一个参数:一个包含一个或多个CSS 选择器的字符串(多个选择器以逗号分隔),返回匹配指定CSS选择器的第一个元素节点(无法选中CSS伪元素),没有发现匹配的节点则返回null。

语法:

element = document.querySelector(selectors);

示例:一个强大的选择方式

<div class="user-panel main">
  <input name="login"/> //这个标签将被返回
</div>

<script>
  var el = document.querySelector("div.user-panel.main input[name=login]");
</script>

示例:如果要匹配的ID或选择器不符合 CSS 语法(比如不恰当地使用了冒号或者空格),你必须用反斜杠将这些字符转义。由于 JavaScript 中,反斜杠是转义字符,所以当你输入一个文本串时,你必须将它转义两次(一次是为 JavaScript 字符串转义,另一次是为 querySelector 转义):

<div id="foo\bar"></div>
<div id="foo:bar"></div>

<script>
 console.log('#foo\bar')        // "#fooar"
 document.querySelector('#foo\bar')  // 不匹配任何元素

 console.log('#foo\\bar')       // "#foo\bar"
 console.log('#foo\\\\bar')      // "#foo\\bar"
 document.querySelector('#foo\\\\bar') // 匹配第一个div

 document.querySelector('#foo:bar')  // 不匹配任何元素
 document.querySelector('#foo\\:bar') // 匹配第二个div
</script>

示例:删除

  <div id="myDiv">
    <p class="myP">hello world</p>
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>
  <script>
    var div = document.getElementById("myDiv");
    console.log(div); //(11)
    var p = document.querySelector("p");
    div.removeChild(p);
    console.log(p); //(12)
  </script>
//(11)处打印值
  <div id="myDiv">
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>

//(12)处打印值
    <p class="myP">hello world</p> //如你所见,querySelector也是静态的快照

6、querySelectorAll():

接收一个参数:一个包含一个或多个CSS 选择器的字符串(多个选择器以逗号分隔),返回静态NodeList对象集合,该集合中包含匹配指定CSS选择器的所有节点,元素节点的变化无法实时反映在结果中;如果参数中包含CSS伪元素则返回一个空的对象集合。

语法:

elementList = document.querySelectorAll(selectors);

示例:

var matches = document.querySelectorAll("div.note, div.alert");

示例:删除

  <div id="myDiv">
    <p class="myP">hello world</p>
    <p class="myP">hello dolby</p>
    <p class="myP">hello dot</p>
    <p class="myP">hello bean</p>
  </div>
  <script>
    var div = document.getElementById("myDiv");
    console.log(div); //(13)
    var p = document.querySelectorAll("p");
    for (var i = 0; i < p.length; i++) {
      div.removeChild(p[i]);
    }
    console.log(p); //(14)
  </script>
//(13)处打印值
  <div id="myDiv"></div>
//(13)处打印值
  [p.myP,p.myP,p.myP,p.myP] //返回的是静态NodeList集合,元素节点的变化无法实时反映在结果中

7、elementFromPoint():

接收两个参数:分别是相对于当前窗口左上角的横纵坐标,单位为CSS像素,不需要加单位;返回位于页面指定位置的元素,如果该元素不可返回(如滚动条)则返回它的父元素,如果坐标值无意义(如负值)则返回null。

语法

var element = document.elementFromPoint(x, y);

示例:

<!DOCTYPE html>
<html lang="en">
<head>
<title>elementFromPoint example</title>

<script>
function changeColor(newColor) {
 elem = document.elementFromPoint(2, 2);
 elem.style.color = newColor;
}
</script>
</head>

<body>
<p id="para1">Some text here</p>
<button onclick="changeColor('blue');">blue</button>
<button onclick="changeColor('red');">red</button>
</body>
</html>

这一个获取元素的方法用得不多所以不多做介绍。

是不是觉得看了上面这些头好大啊,什么是动态什么是静态,有没有好记一点的方法呢?
有哒!

你可以简单地理解为,getElementBy系列返回的都是动态的HTMLCollection集合,动态集合中的DOM结构变化能实时地反映到所保存的对象中,而querySelector系列返回的都是静态的NodeList对象,是一个快照,对DOM的任何操作都不会对其产生影响。

那么Nodelist和HTMLCollection有什么异同呢?

相同点:

  • 二者都是类数组对象
  • 二者都具有length属性
  • 二者都具有item()方法
  • 二者都是动态的元素集合,每次访问都需要重新对文档进行查询。

你一定会好奇,诶?前面不是说querySelector系列返回的都是静态的NodeList对象咩?怎么又变成动态的呢?原因在此:

规范中对 querySelectorAll 有明确要求,规定其必须返回一个静态的 NodeList 对象。

在Chrome中情况如下:

document.querySelectorAll('a').toString();  // return "[object NodeList]"
document.getElementsByTagName('a').toString();  // return "[object HTMLCollection]"

不同点:

NodeList 对象会包含文档中的所有节点,如 Element、Text 和 Comment 等;HTMLCollection 对象只会包含文档中的 Element 节点。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js正确获取元素样式详解

    在说js获取元素样式之前,简单地谈一下样式 样式分三种 外部样式 External Style Sheet 以CSS为扩展名的文件(又称为"超文本样式表"文件),它的作用范围可以是多张网页,或整个网站,甚至不同的网站.与网页链接后,才能应用. 嵌入式样式 internal Style Sheet 包含在网页内部的样式设置,它的作用范围仅限于嵌入的网页. 内联式样式 inline Style 在HTML文档中,内联式样式表的格式化信息直接插入所应用的网页元素的HTML标签中,作为其HTM

  • js jquery获取当前元素的兄弟级 上一个 下一个元素

    var chils= s.childNodes;  //得到s的全部子节点 var par=s.parentNode;   //得到s的父节点 var ns=s.nextSbiling;   //获得s的下一个兄弟节点 var ps=s.previousSbiling;  //得到s的上一个兄弟节点 var fc=s.firstChild;   //获得s的第一个子节点 var lc=s.lastChile;   //获得s的最后一个子节点 JS获取节点父级,子级元素 先说一下JS的获取方法,其

  • 用js获取元素属性的代码

    获取元素属性 // [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

  • JavaScript中获取HTML元素值的三种方法

    JavaScript中取得元素的方法有三种:分别是: 1.getElementById() 方法:通过id取得HTML元素. 2.getElementsByName()方法:通过name取得元素,是一个数组. 3.getElementsByTagName()方法:通过HTML标签取得元素,是一个数组. 如果要取得值可以使用value,如:var x=document.getElementById("id").value; 方法一:getElementById() 方法 可返回对拥有指定

  • JavaScript中常见获取元素的方法汇总

    常见的获取元素的方法有3种,分别是通过元素ID.通过标签名字和通过类名字来获取. getElementById DOM提供了一个名为getElementById的方法,这个方法将返回一个与之对应id属性的节点对象.使用的时候请注意区分大小写. 它是document对象特有的函数,只能通过其来调用该方法.其使用的方法如下: 复制代码 代码如下: document.getElementById('demo') //demo是元素对应的ID 该方法兼容主流浏览器,甚至包括IE6+,可以大胆使用. ge

  • 浅谈JS获取元素的N种方法及其动静态讨论

    实际前端开发工作中,我们经常会遇到要获取某些元素,以达到更新该元素的样式.内容等目的.而文档对象模型 (DOM) 是HTML和XML文档的编程接口,它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容.DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合,它会将web页面和脚本或程序语言连接起来.也因此,JavaScript可以通过DOM API获取元素节点,方法有如下几种:其中querySelector()和quer

  • 浅谈JS前端模块化的几种规范

    前言 有这样一个场景,客户端运行很久,但是法务部和数据部需要收集用户的一些信息,这些信息收集好之后需要进行相应的数据处理,之后上报到服务端.客户端提供一个纯粹的js执行引擎,不需要 WebView 容器.iOS 端有成熟的JavaScriptCore.Android 可以使用 V8 引擎.这样一个引擎配套有一个 SDK,访问 Native 的基础能力和数据运算能力,可以看成是一个阉割版的 Hybrid SDK 额外增加了一些数据处理能力. 问题结束了吗?处理逻辑的时候还需要用到2个库:cheer

  • 浅谈js获取ModelAndView值的问题

    JS当中不能接收ModelAndView的返回值吗?一定要在JSP页面中才能接收吗? 1 方法一 [有效] 可以的,跟el表达式访问方式一样. 示例代码,一个数据展示请求的Action中存入一个userId: @RequestMapping(value="/diary") public ModelAndView toDiaryList(HttpSession session){ ModelAndView view = new ModelAndView("/diary_list

  • 浅谈shell 遍历数组的几种方法

    背景 某天遇到一个问题,现象如下:第一种遍历正常打印元素,然而第二种遍历只会打印一个元素! #!/bin/bash # $1 代表文件目录 # 执行 eg: # sh your_shell.sh /user/lib/ echo "开始时间:`date '+%Y-%m-%d %H:%M:%S'`" # 1.获取所有的 file files=`ls $1` # 2.定义 1个数组变量 declare -a array_files01 # 数组 index 初始化为 0 m1=0 # 遍历

  • js获取元素的标签名实现方法

    有时候我们想获取到一个标签的名称,例如:<div>a</div>得到"div".请看下面的例子: 页面上有一个class="a"的标签,可能是input,也可能是普通的div或者是span标签,现在我们要往这个标签加一个值"value1".如果是input则将其value属性设置为value1,div则将其innerHTML设置为value1.如何实现呢-- 如果纯js实现如下: //找到这个标签的代码略 this 代表找

  • 原生js获取元素样式的简单方法

    我们在开发过程中经常会遇到通过js获取或者改变DOM元素的样式,方法有很多,比如:通过更改DOM元素的class.现在我们讨论原生js来获取DOM元素的CSS样式,注意是获取不是设置 在开始之前先说下获取最终应用在元素上的所有CSS属性对象的意思是,如果没有给元素设置任何样式,也会把浏览器默认的样式返回来. 1.ele.style 在学习DOM的时候就看到通过ele.style来获取元素样式值,但是有时候获取的并非是节点的样式值,而是空值.这是因为ele.style只能获取写在元素标签中的sty

  • 浅谈js中StringBuffer类的实现方法及使用

    如下所示: <strong>JAVA中有一个StringBuffer类,js中却没有下面来自己实现一个简单的js的StringBuffer类.</strong> //创建一个StringBuffer类 ,此类有两个方法:一个是append方法一个是toString方法 function StringBuffer() { this.__strings__ = []; }; StringBuffer.prototype.append = function(str) { this.__s

  • 浅谈javascript获取元素transform参数

    之前写页面的时候有试过想用js获取某些元素的translate的数值什么的,但是translate又是transform的子样式(勉强说说),理所当然就是先获取transform样式,再读里面的值. 复制代码 代码如下: body{-webkit-transform: translateX(20px);} 但当我尝试这样做的时候,奇迹出现了: 当时我的内心几乎是崩溃的,我只想安安静静的获取translate的值而已啊,谁知给我弹出这货,虽然上高数课的时候也有讲到所有变化(二维.三维)效果都可以浓

  • JS动态创建元素的两种方法

    本文为大家分享了js创建元素的两种方法供大家参考,具体内容如下 1)将需要创建的元素,以字符串的形式拼接:找到父级元素,直接对父级元素的innnerHTML进行赋值. 2)使用Document.Element对象自带的一些函数,来实现动态创建元素(创建元素 => 找到父级元素 => 在指定位置插入元素) 一.字符串拼接形式 为了更好的理解,设定一个应用场景. 随机生成一组数字,将这组数据渲染为条形图的形式,放在div[id="container"]中,如下图 <div

  • 浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序

    在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Literals): var fnMethodName = function(x){alert(x);} Function()构造函数: var fnMethodName = new Function('x','alert(x);') // 由Function构造函数的参数个数可变.最后一个参数写函数体

随机推荐