Javascript 是否有跨浏览器和跨框架的方法来检查对象是否是HTML元素?

Javascript 是否有跨浏览器和跨框架的方法来检查对象是否是HTML元素?,javascript,html,dom,cross-browser,Javascript,Html,Dom,Cross Browser,给定一个对象obj,我想检查该对象是否是本机HTML元素。我可以做到: if ( obj instanceof HTMLElement ) 但这不适用于跨帧(例如,对来自的对象),因为每个帧都有自己的HTMLElement构造函数。或者,我可以这样做: if ( obj.tagName ) 但这并不安全/可靠,因为这样的属性可以(非)故意添加到对象中 那么,有可靠的方法来实现这一点吗?我知道的最好的方法是检查对象的toString表示 对于HtmleElement的字符串表示,有两件事始终

给定一个对象
obj
,我想检查该对象是否是本机HTML元素。我可以做到:

if ( obj instanceof HTMLElement )
但这不适用于跨帧(例如,对来自
的对象),因为每个帧都有自己的
HTMLElement
构造函数。或者,我可以这样做:

if ( obj.tagName ) 
但这并不安全/可靠,因为这样的属性可以(非)故意添加到对象中


那么,有可靠的方法来实现这一点吗?

我知道的最好的方法是检查对象的toString表示

对于HtmleElement的字符串表示,有两件事始终是正确的:

  • 它将以
    [对象HTML
  • 它将以
    元素]
  • 下面是详细的检查方法:

    var str = Object.prototype.toString.call(obj),
        isHtmlElement = str.indexOf('[object HTML') === 0 
                     && str.indexOf('Element]') > -1;
    

    仍然存在一些(但最小)误报的可能性。

    您可以使用nodeType和nodeName属性,不幸的是,如果将这些属性添加到非HTML元素对象中,您仍然会遇到问题


    isPrototypeOf
    功能如何
    HTMLElement.prototype.isPrototypeOf(obj)
    对于任何HTML元素都应该返回
    true
    ,但是对于某些随机对象应该返回
    false


    我还没有机会跨帧测试它,所以我唯一担心的是它是否会遇到与
    instanceOf
    相同的问题

    您可以使用以下内容,接受这样一个事实,即这只适用于支持
    HTMLElement
    作为基本构造函数的UAs:

    /// testing vars
    var localBody = document.body;
    var foreignBody = document.getElementById('iframe').contentDocument.body;
    
    /// useful function
    var deriveWindow = function( elm ){
        return elm && 
            elm.ownerDocument && 
            (elm.ownerDocument.defaultView || 
            elm.ownerDocument.parentWindow)
        ;
    };
    
    /// instanceofs
    console.log( localBody instanceof HTMLElement );
    console.log( foreignBody instanceof HTMLElement );
    console.log( localBody instanceof deriveWindow(localBody).HTMLElement );
    console.log( foreignBody instanceof deriveWindow(foreignBody).HTMLElement );
    
    输出将因浏览器而异,Firefox 25(在Windows 7上)提供:

    而IE 11、Opera 12、Safari 5和Chrome 31(在Windows 7上)都提供:

    true
    false
    true
    true
    
    小提琴:


    这也是下划线.js使用的方法<代码>.\uj.isElement=function(obj){return!!(obj&&obj.nodeType==1);}element.outerHTML.match(/^ES6:
    var-ishtmlement=object=>{var-string={}.toString.call(对象);return string.startsWith('[object HTML')&&string.endsWith('element');};
    请参阅:主机对象
    [[Class]]
    名称依赖于实现-
    ({}).toString.call(document.documentElement)='[object对象]“
    在IE 6和7中,以及
    HTML*元素
    接口不公开。
    true
    true
    true
    true
    
    true
    false
    true
    true