在JavaScript中测试DOM元素的类型

107

在JavaScript中有没有一种方法可以测试元素的类型?

答案可能需要使用原型库,但以下设置确实使用了该库。

function(event) {
  var element = event.element();
  // if the element is an anchor
  ...
  // if the element is a td
  ...
}

你不是在询问类型,类型可能是一个对象。你所要求的是标签,正如答案中提到的那样,即 tagName 属性。 - Soldeplata Saketos
7个回答

135

您可以使用typeof(N)来获取实际对象类型,但您想要做的是检查标记,而不是DOM元素的类型。

在这种情况下,请使用elem.tagNameelem.nodeName属性。

如果希望更有创意,可以使用标签名称字典和匿名闭包,而不是 switch 或 if/else。


77
if (element.nodeName == "A") {
 ...
} else if (element.nodeName == "TD") {
 ...
}

1
有时候是这样的。不管怎样,你总可以使用 element.nodeName.match(/\bTBODY\b/i) 或者 element.nodeName.toLowerCase() == 'tbody' 等等。 - Robusto
10
@Robusto 是错误的。如果文档是HTML且DOM实现正确,则元素始终为大写形式。根据http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-104682815中的“tagName”部分(对于元素nodeName == tagName),“无论源HTML文档中的大小写如何,HTML DOM都以规范化的大写形式返回HTML元素的标记名称。” - bobwienholt

21

也许你还需要检查节点类型:

if(element.nodeType == 1){//element of type html-object/tag
  if(element.tagName=="a"){
    //this is an a-element
  }
  if(element.tagName=="div"){
    //this is a div-element
  }
}

编辑:已更正节点类型值


4
注意tagName的情况。 - eyelidlessness
@Casey:它将在HTML页面中显示;在XHTML页面中,标签的大小写是保留的(因此,在HTML页面中,“a”将变成“A”,而在XHTML页面中则为“a”):http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-104682815(假设XHTML页面已正确提供并且未作为“text/html”提供。) - T.J. Crowder
2
@T.J.Crowder 看起来最好的选择是 element.tagName.toLowerCase() === 'a' - p3drosola
@Ped:是的,或者如果可能element实际上不是元素(例如,如果您还没有执行上面列出的nodeType == 1检查),则为element.nodeName.toLowerCase()Node接口具有nodeName。对于Element实例,它与tagName相同。对于其他类型的节点,它是诸如“#text”或“#document”的内容。不过,我认为我总是会使用nodeType检查。 - T.J. Crowder
2019年更新:至少在现代Chromium(v79.0.3945.79)中,标签名字符串是大写的。“对于表示HTML文档的DOM树,返回的标签名始终以规范的大写形式呈现。例如,在<div>元素上调用tagName将返回“DIV”。” https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName正确的比较方式应该是 node.tagName == 'DIV' - marcs

6

roenving是正确的,但您需要将测试更改为:

if(element.nodeType == 1) {
//代码
}

因为nodeType为3实际上是文本节点,而nodeType为1是HTML元素。请参见http://www.w3schools.com/Dom/dom_nodetype.asp


4
虽然之前的答案已经完美解决了问题,但我想再介绍一种方式,即可以使用它们实现的接口对元素进行分类。
请参阅W3 Org以获取可用接口

console.log(document.querySelector("#anchorelem") instanceof HTMLAnchorElement);
console.log(document.querySelector("#divelem") instanceof HTMLDivElement);
console.log(document.querySelector("#buttonelem") instanceof HTMLButtonElement);
console.log(document.querySelector("#inputelem") instanceof HTMLInputElement);
<a id="anchorelem" href="">Anchor element</a>
<div id="divelem">Div Element</div>
<button id="buttonelem">Button Element</button>
<br><input id="inputelem">

接口检查可以通过两种方式进行,分别是 elem instanceof HTMLAnchorElement 或者 elem.constructor.name == "HTMLAnchorElement",两种方式都会返回 true


2

我通常从toString()返回值中获取它。它可以在不同访问的DOM元素中工作:

var a = document.querySelector('a');

var img = document.createElement('img');

document.body.innerHTML += '<div id="newthing"></div>';
var div = document.getElementById('newthing');

Object.prototype.toString.call(a);    // "[object HTMLAnchorElement]"
Object.prototype.toString.call(img);  // "[object HTMLImageElement]"
Object.prototype.toString.call(div);  // "[object HTMLDivElement]"

然后是相关内容:

Object.prototype.toString.call(...).split(' ')[1].slice(0, -1);

这段代码可以在Chrome、FF、Opera、Edge和IE9+中正常工作(在旧版本的IE中会返回“[object Object]”)。


0

我有另一种测试方式。

Element.prototype.typeof = "element";
var element = document.body; // any dom element
if (element && element.typeof == "element"){
   return true; 
   // this is a dom element
}
else{
  return false; 
  // this isn't a dom element
}


扩展原型通常是一个不好的主意。 - Soldeplata Saketos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接