我想要:

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;
  }
}

有好的替代品吗?


当前回答

使用这里发现的根检测,我们可以确定例如alert是否是对象根的成员,那么它很可能是一个窗口:

function isInAnyDOM(o) { 
  return (o !== null) && !!(o.ownerDocument && (o.ownerDocument.defaultView || o.ownerDocument.parentWindow).alert); // true|false
}

要确定对象是否是当前窗口甚至更简单:

function isInCurrentDOM(o) { 
  return (o !== null) && !!o.ownerDocument && (window === (o.ownerDocument.defaultView || o.ownerDocument.parentWindow)); // true|false
}

这似乎比开头线程中的try/catch解决方案更便宜。

没有P

其他回答

你可能会感兴趣:

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的一部分,第2层。

更新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"
);
}

对于那些使用Angular的:

angular.isElement

https://docs.angularjs.org/api/ng/function/angular.isElement

不是为了强调这一点,而是为了兼容es5的浏览器,为什么不直接:

function isDOM(e) {
  return (/HTML(?:.*)Element/).test(Object.prototype.toString.call(e).slice(8, -1));
}

不会工作在文本节点和不确定的影子DOM或DocumentFragments等,但将工作在几乎所有的HTML标签元素。

旧线程,但这里有一个更新的可能性为ie8和ff3.5用户:

function isHTMLElement(o) {
    return (o.constructor.toString().search(/\object HTML.+Element/) > -1);
}

这是我的版本。它支持来自iframe的元素

/**
 * @param {any} value
 * @param {any} view Optional. If the value is from an iframe, provide the iframe content window here.
 * @returns {boolean}
 */
function isHtmlElement(value, view) {
  if (value instanceof HTMLElement) return true
  if (view && value instanceof view.HTMLElement) return true

  return !!(
    value &&
    typeof value === 'object' &&
    value !== null &&
    value.nodeType === 1 &&
    typeof value.nodeName === 'string'
  )
}