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

Is there a cross-browser and cross-frame way to check if an object is an HTML element?

本文关键字:对象 检查 是否是 HTML 元素 浏览器 框架 是否 方法      更新时间:2023-09-26

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

if ( obj instanceof HTMLElement )

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

if ( obj.tagName ) 

但这并不安全/可靠,因为这样的属性可能是故意添加到对象中的。

那么,有可靠的方法可以做到这一点吗?

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

/// 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上)提供:

true
true
true
true

而IE 11、Opera 12、Safari 5和Chrome 31(在Windows 7上)都给出了:

true
false
true
true

Fiddle:

  • http://jsfiddle.net/9sGx5/7/
  • http://jsfiddle.net/9sGx5/7/embedded/result/

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

http://www.w3schools.com/dom/dom_nodetype.asp

//Returns true if it is a DOM element    
function isElement(o){
    if (typeof o === "object" && o.nodeType === 1 && typeof o.nodeName==="string") {
        return true;
    } 
    return false;    
 }

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

HTMLElement的字符串表示有两件事总是正确的:

  1. 它将从[object HTML开始
  2. 它将以Element]结束

以下是详细的检查方法:

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

假阳性的可能性仍然存在(但微乎其微)。

isPrototypeOf函数怎么样?HTMLElement.prototype.isPrototypeOf(obj)应该为任何HTML元素返回true,但为某些随机对象返回false

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