【问题标题】:Is there a cross-browser and cross-frame way to check if an object is an HTML element?是否有跨浏览器和跨框架的方法来检查对象是否是 HTML 元素?
【发布时间】:2013-12-29 20:55:22
【问题描述】:

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

if ( obj instanceof HTMLElement )

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

if ( obj.tagName ) 

但这不安全/不可靠,因为这样的属性可能(非)有意添加到对象中。

那么,有没有可靠的方法来做到这一点?

【问题讨论】:

  • element.outerHTML.match(/^

标签: javascript html dom cross-browser


【解决方案1】:

您可以使用以下内容,接受这样一个事实,即这仅适用于支持 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

小提琴:

【讨论】:

    【解决方案2】:

    您可以使用 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;    
     }
    

    【讨论】:

    • 这也是underscore.js使用的方法。 _.isElement = function(obj) { return !!(obj && obj.nodeType === 1); };
    【解决方案3】:

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

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

    1. 将以[object HTML开头
    2. 它将以Element] 结尾

    这里是详细的检查方法:

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

    仍有一些(但极少)误报的可能性。

    【讨论】:

    • ES6: var isHTMLElement = object => { var string = {}.toString.call(object); return string.startsWith('[object HTML') && string.endsWith('Element]'); };
    • 参见 github.com/lodash/lodash/issues/427#issuecomment-30357634:主机对象 [[Class]] 名称取决于实现 — IE 6 和 7 中的 ({}).toString.call(document.documentElement) == '[object Object]'HTML*Element 接口未公开。
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-08-10
      • 2011-12-07
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多