How do you check if a JavaScript Object is a DOM Object?

后端 未结 30 2520
-上瘾入骨i
-上瘾入骨i 2020-11-22 16:06

I\'m trying to get:

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

In my own scripts, I used

相关标签:
30条回答
  • 2020-11-22 16:31

    I think that what you have to do is make a thorough check of some properties that will always be in a dom element, but their combination won't most likely be in another object, like so:

    var isDom = function (inp) {
        return inp && inp.tagName && inp.nodeName && inp.ownerDocument && inp.removeAttribute;
    };
    
    0 讨论(0)
  • 2020-11-22 16:32

    old thread, but here's an updated possibility for ie8 and ff3.5 users:

    function isHTMLElement(o) {
        return (o.constructor.toString().search(/\object HTML.+Element/) > -1);
    }
    
    0 讨论(0)
  • 2020-11-22 16:32

    According to mdn

    Element is the most general base class from which all objects in a Document inherit. It only has methods and properties common to all kinds of elements.

    We can implement isElement by prototype. Here is my advice:

    /**
     * @description detect if obj is an element
     * @param {*} obj
     * @returns {Boolean}
     * @example
     * see below
     */
    function isElement(obj) {
      if (typeof obj !== 'object') {
        return false
      }
      let prototypeStr, prototype
      do {
        prototype = Object.getPrototypeOf(obj)
        // to work in iframe
        prototypeStr = Object.prototype.toString.call(prototype)
        // '[object Document]' is used to detect document
        if (
          prototypeStr === '[object Element]' ||
          prototypeStr === '[object Document]'
        ) {
          return true
        }
        obj = prototype
        // null is the terminal of object
      } while (prototype !== null)
      return false
    }
    console.log(isElement(document)) // true
    console.log(isElement(document.documentElement)) // true
    console.log(isElement(document.body)) // true
    console.log(isElement(document.getElementsByTagName('svg')[0])) // true or false, decided by whether there is svg element
    console.log(isElement(document.getElementsByTagName('svg'))) // false
    console.log(isElement(document.createDocumentFragment())) // false

    0 讨论(0)
  • 2020-11-22 16:33

    This might be of interest:

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

    It's part of the DOM, Level2.

    Update 2: This is how I implemented it in my own library: (the previous code didn't work in Chrome, because Node and HTMLElement are functions instead of the expected object. This code is tested in FF3, IE7, Chrome 1 and 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"
    );
    }
    
    0 讨论(0)
  • 2020-11-22 16:36

    Perhaps this is an alternative? Tested in Opera 11, FireFox 6, Internet Explorer 8, Safari 5 and Google Chrome 16.

    function isDOMNode(v) {
      if ( v===null ) return false;
      if ( typeof v!=='object' ) return false;
      if ( !('nodeName' in v) ) return false; 
    
      var nn = v.nodeName;
      try {
        // DOM node property nodeName is readonly.
        // Most browsers throws an error...
        v.nodeName = 'is readonly?';
      } catch (e) {
        // ... indicating v is a DOM node ...
        return true;
      }
      // ...but others silently ignore the attempt to set the nodeName.
      if ( v.nodeName===nn ) return true;
      // Property nodeName set (and reset) - v is not a DOM node.
      v.nodeName = nn;
    
      return false;
    }
    

    Function won't be fooled by e.g. this

    isDOMNode( {'nodeName':'fake'} ); // returns false
    
    0 讨论(0)
  • 2020-11-22 16:37

    This could be helpful: isDOM

    //-----------------------------------
    // Determines if the @obj parameter is a DOM element
    function isDOM (obj) {
        // DOM, Level2
        if ("HTMLElement" in window) {
            return (obj && obj instanceof HTMLElement);
        }
        // Older browsers
        return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
    }
    

    In the code above, we use the double negation operator to get the boolean value of the object passed as argument, this way we ensure that each expression evaluated in the conditional statement be boolean, taking advantage of the Short-Circuit Evaluation, thus the function returns true or false

    0 讨论(0)
提交回复
热议问题