当前位置:  开发笔记 > 编程语言 > 正文

JavaScript isDOM - 如何检查JavaScript对象是否是DOM对象?

如何解决《JavaScriptisDOM-如何检查JavaScript对象是否是DOM对象?》经验,为你挑选了6个好方法。

我想要:

document.createElement('div')  //=> true
{tagName: 'foobar something'}  //=> false

在我自己的脚本中,我曾经只是使用它,因为我从来不需要tagName作为属性:

if (!object.tagName) throw ...;

因此,对于第二个对象,我想出了以下作为快速解决方案 - 主要是有效的.;)

问题是,它取决于执行只读属性的浏览器,而不是所有人都这样做.

function isDOM(obj) {
  var tag = obj.tagName;
  try {
    obj.tagName = '';  // Read-only for DOM, should throw exception
    obj.tagName = tag; // Restore for normal objects
    return false;
  } catch (e) {
    return true;
  }
}

有一个很好的替代品吗?



1> some..:

这可能是有趣的:

function isElement(obj) {
  try {
    //Using W3 DOM2 (works for FF, Opera and Chrome)
    return obj instanceof HTMLElement;
  }
  catch(e){
    //Browsers not supporting W3 DOM2 don't have HTMLElement and
    //an exception is thrown and we end up here. Testing some
    //properties that all elements have (works on IE7)
    return (typeof obj==="object") &&
      (obj.nodeType===1) && (typeof obj.style === "object") &&
      (typeof obj.ownerDocument ==="object");
  }
}

它是DOM的一部分,Level2.

更新2:这是我在自己的库中实现的方式:(之前的代码在Chrome中不起作用,因为Node和HTMLElement是函数而不是预期的对象.此代码在FF3,IE7,Chrome 1和Opera中进行测试9).

//Returns true if it is a DOM node
function isNode(o){
  return (
    typeof Node === "object" ? o instanceof Node : 
    o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
  );
}

//Returns true if it is a DOM element    
function isElement(o){
  return (
    typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
    o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
);
}


值得注意的是,这不适用于属于其他窗口/框架的元素.鸭子打字是推荐的方法
WTF事实:Firefox 5及更早版本为`[] instanceof HTMLElement`返回`true`.
顺便说一下,`HTMLElement`总是一个`函数`,所以`typeof`会让你离开轨道并执行语句的第二部分.你可以尝试`instanceof Object`,因为该函数将是`Object`的一个实例,或者只是显式检查`typeof ==="function"`,因为`Node`和`HTMLElement`都是本机对象功能.
当你调用`isElement(0)`时,它返回0,而不是false ...为什么这样,我怎么能阻止它呢?

2> Monarch Wadi..:

以下IE8兼容,超简单代码完美运行.

该接受的答案没有检测到所有类型的HTML元素.例如,不支持SVG元素.相比之下,这个答案适用于HTML和SVG.

在这里看到它:https://jsfiddle.net/eLuhbu6r/

function isElement(element) {
    return element instanceof Element || element instanceof HTMLDocument;  
}


我认为仍然使用IE7的人应该花5秒时间下载更好的浏览器,而不是把它放在我们身上投入数天或数周来解决他们拒绝与时俱进的问题.
IE7上的"元素"未定义

3> Eugene Lazut..:

上面和下面的所有解决方案(包括我的解决方案)都有可能出错,特别是在IE上 - 很有可能(重新)定义一些对象/方法/属性来模仿DOM节点,使得测试无效.

所以我通常使用鸭子式的测试:我专门测试我使用的东西.例如,如果我想克隆一个节点,我会像这样测试它:

if(typeof node == "object" && "nodeType" in node &&
   node.nodeType === 1 && node.cloneNode){
  // most probably this is a DOM node, we can clone it safely
  clonedNode = node.cloneNode(false);
}

基本上它是一个小的健全性检查+我计划使用的方法(或财产)的直接测试.

顺便提一下,上面的测试对所有浏览器上的DOM节点都是一个很好的测试.但是,如果您想要安全起见,请始终检查方法和属性的存在并验证其类型.

编辑: IE使用ActiveX对象来表示节点,因此它们的属性不像真正的JavaScript对象,例如:

console.log(typeof node.cloneNode);              // object
console.log(node.cloneNode instanceof Function); // false

而它应该true分别返回"功能" .测试方法的唯一方法是查看是否已定义.



4> Greg..:

您可以尝试将其附加到真正的DOM节点......

function isDom(obj)
{
    var elm = document.createElement('div');
    try
    {
        elm.appendChild(obj);
    }
    catch (e)
    {
        return false;
    }

    return true;
}


这有用吗?它仍然是一个解决方案.那个有创意的人.
我差不多5年后就开始读这篇文章了,我认为这是最酷的之一.它只需要改进.例如,您可以尝试将节点的*clone*附加到分离的元素.如果那不是DOM对象.肯定会出问题.但是,这仍然是一个非常昂贵的解
+1提供的创造力和确定性.但是,如果节点恰好是DOM的一部分,那么你刚刚删除了它!所以......如果没有做必要的工作来重新添加元素到DOM,这个答案是不完整的.

5> mightyiam..:

Lo-Dash_.isElement怎么样?

$ npm install lodash.iselement

并在代码中:

var isElement = require("lodash.iselement");
isElement(document.body);



6> finpingvin..:

这是来自可爱的JavaScript库MooTools:

if (obj.nodeName){
    switch (obj.nodeType){
    case 1: return 'element';
    case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
    }
}


此代码不断言该对象是DOM元素; 只是它看起来有点像一个.可以为任何对象提供nodeName和nodeType属性并满足此代码.
推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有