JavaScript 객체가 DOM 객체인지 어떻게 확인합니까?


248

나는 노력하고있다 :

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

좋은 대체물이 있습니까?


3
"DOM 객체"가 요소뿐만 아니라 모든 노드 (텍스트 노드, 속성 등)를 다루어야하는지 궁금해 하는가? 모든 답변과 질문을 제기 한 방식은이 질문이 Elements에 관한
mike rodent

답변:


300

이것은 관심이있을 수 있습니다 :

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, Level2 의 일부입니다 .

업데이트 2 : 이것은 내 라이브러리에서 구현 한 방법입니다. (노드와 HTMLElement가 예상 객체 대신 함수이기 때문에 이전 코드는 Chrome에서 작동하지 않았습니다.이 코드는 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"
);
}

11
다른 창 / 프레임에 속하는 요소에서는 작동하지 않습니다. 오리 타이핑이 권장되는 접근법
Andy E

2
다음과 같이 속일 수 있습니다.function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
Kernel James

11
WTF 사실 : Firefox 5 및 이전 버전은을 반환 true합니다 [] instanceof HTMLElement.
Rob W

6
Btw HTMLElement는 항상 function이므로 typeof트랙에서 벗어나서 명령문의 두 번째 부분을 실행합니다. 당신은 당신이 원하는 경우 시도 할 수 instanceof Object함수의 인스턴스가 될 것이기 때문에, Object또는 단지 명시 적으로 확인 typeof === "function"하기 때문에 Node그리고 HTMLElement네이티브 오브젝트의 기능은 다음과 같습니다.
Roland

2
을 호출하면 isElement(0)false가 아닌 0을 반환합니다. 왜 그런지, 어떻게 방지 할 수 있습니까?
Jessica

68

다음 IE8 호환 초간단 코드는 완벽하게 작동합니다.

허용 대답은 HTML 요소의 모든 유형을 감지하지 않습니다. 예를 들어 SVG 요소는 지원되지 않습니다. 대조적으로,이 답변은 SVG뿐만 아니라 HTML에도 효과적입니다.

https://jsfiddle.net/eLuhbu6r/ 에서 실제 작업을 확인하십시오.

function isElement(element) {
    return element instanceof Element || element instanceof HTMLDocument;  
}

3
IE7에서는 '요소'가 정의되어 있지 않음
Dan

49
IE7을 계속 사용하는 사람은 5 일 동안 더 나은 브라우저를 다운로드하는 데 시간을 투자하지 않고 며칠 또는 몇 주를 투자하는 대신 더 나은 브라우저를 다운로드해야한다고 생각합니다.
mopsyd

1
@mopsyd에 동의하지만 답변 작성자는 IE7에서 작동하며 정확성을 위해 업데이트해야 할 수도 있다고 말합니다.
Lajos Meszaros

1
IE9로 업데이트되었습니다. IE8이 지원하는지 확실하지 않습니다.
군주 와디아

1
@MonarchWadia 예 IE8에서 지원됩니다. 그러나 이것은 document모든 브라우저에서 요소에 대해 true를 반환하지는 않습니다 . 필요한 경우 다음을 시도해야합니다.x instanceof Element || x instanceof HTMLDocument
S.Serpooshan

11

위와 아래의 모든 솔루션 (내 솔루션 포함)은 특히 IE에서 부정확 할 가능성이 있습니다. 테스트를 무효화하는 DOM 노드를 모방하기 위해 일부 객체 / 메소드 / 속성을 재정의하는 것이 가능합니다.

일반적으로 오리 타이핑 스타일 테스트를 사용합니다. 사용하는 것을 구체적으로 테스트합니다. 예를 들어 노드를 복제하려면 다음과 같이 테스트하십시오.

if(typeof node == "object" && "nodeType" in node &&
   node.nodeType === 1 && node.cloneNode){
  // most probably this is a DOM node, we can clone it safely
  clonedNode = node.cloneNode(false);
}

기본적으로 그것은 약간의 건강 검사 + 내가 사용할 계획 (또는 재산)에 대한 직접 테스트입니다.

또한 위의 테스트는 모든 브라우저에서 DOM 노드에 대한 좋은 테스트입니다. 그러나 안전한면을 유지하려면 항상 메소드와 속성의 존재를 확인하고 유형을 확인하십시오.

편집 : IE는 ActiveX 객체를 사용하여 노드를 나타내므로 해당 속성이 실제 JavaScript 객체로 작동하지 않습니다.

console.log(typeof node.cloneNode);              // object
console.log(node.cloneNode instanceof Function); // false

"function"및 true각각을 반환해야합니다 . 메소드를 테스트하는 유일한 방법은 메소드가 정의되어 있는지 확인하는 것입니다.


"document.body.cloneNode 대해서 typeof"내 IE에 반환 "개체를"않습니다
데니스 C

이것은 괜찮은 대답처럼 보입니다. 하지만 내 대답은 아래를 참조 stackoverflow.com/a/36894871/1204556
군주 와디아

8

실제 DOM 노드에 추가 할 수 있습니다 ...

function isDom(obj)
{
    var elm = document.createElement('div');
    try
    {
        elm.appendChild(obj);
    }
    catch (e)
    {
        return false;
    }

    return true;
}

11
이 작동합니까? 여전히 해결책입니다. 그 창조적 인 것.
저스틴 메이어

3
창의성과 확실성에 +1. 그러나 노드가 이미 DOM의 일부인 경우 방금 제거했습니다! 따라서 ... 필요한 경우 요소를 DOM에 다시 추가하는 작업을 수행하지 않고도이 답변은 불완전합니다.
svidgen

4
나는 거의 5 년 후에 이것을 읽고 있으며, 그것이 가장 멋진 것 중 하나라고 생각합니다. 다듬어야합니다. 예를 들어, 노드 복제본 을 분리 된 요소 에 추가 할 수 있습니다 . 이것이 DOM 객체가 아닌 경우. 무언가 잘못 될 것입니다. 그래도 여전히 비싼 솔루션입니다.
MaxArt

또는 요소 의 복제본 을 추가하는 대신 복제 하려고하면 충분 obj.cloneNode(false)합니다. AND 는 부작용이 없습니다.
mauroc8

1
이것은 실제로 비싸고 불필요하게 복잡합니다. 내 대답은 아래 참조 stackoverflow.com/a/36894871/1204556
군주 와디아


6

방법에 대한 소호 - 대시의_.isElement ?

$ npm install lodash.iselement

그리고 코드에서 :

var isElement = require("lodash.iselement");
isElement(document.body);

1
나는이 해결책을 좋아한다. 간단하고, 여기에서 가장 높은 투표 솔루션과 달리 별도의 iframe에있는 요소에 대해서도 Edge 및 IE에서 작동합니다.
엘리아스 자 마리아

브라우저에서 NPM 모듈을 실행하려면 Webpack이 필요하지만이 답변이 도움이됩니다.
Edwin Pratt

5

이것은 멋진 JavaScript 라이브러리 MooTools 에서 가져온 것입니다 .

if (obj.nodeName){
    switch (obj.nodeType){
    case 1: return 'element';
    case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
    }
}

12
이 코드는 객체가 DOM 요소라고 주장하지 않습니다. 단지 하나처럼 보일뿐입니다. 모든 오브젝트에는 nodeName 및 nodeType 특성이 제공 될 수 있으며이 코드를 만족시킵니다.
thomasrutter

이 답변은 모든 유형의 HTML 요소를 감지하지는 않습니다. 예를 들어 SVG 요소는 지원되지 않습니다. 아래 답변을 참조하십시오.
Monarch Wadia

SVG와 같은 모든 요소에서 실제로 작동하지는 않습니다. 내 대답은 아래 참조 stackoverflow.com/a/36894871/1204556
군주 와디아

4

여기에 있는 근 탐지 기능을 사용하여 예를 들어 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 솔루션보다 저렴합니다.

돈 피


최신 Chrome 및 FF와 IE11 에서도이 테스트를 수행 document.createElement()했으며 DOM을 통해 생성 되었지만 삽입되지 않은 텍스트 노드 및 객체에서도 모든 곳에서 작동합니다 . 놀라운 (: 감사합니다
Geradlus_RU

비록 내 것이 같은 일을 많이하고 덜 복잡하지만 이것은 괜찮은 대답처럼 보입니다. stackoverflow.com/a/36894871/1204556
Monarch Wadia

4

오래된 스레드이지만 다음은 ie8 및 ff3.5 사용자에게 업데이트 된 가능성입니다 .

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

4

변수가 DOM 요소인지 테스트하는 간단한 방법을 제안합니다

function isDomEntity(entity) {
  if(typeof entity  === 'object' && entity.nodeType !== undefined){
     return true;
  }
  else{
     return false;
  }
}

또는 HTMLGuy가 제안한대로 :

const isDomEntity = entity => {
  return typeof entity   === 'object' && entity.nodeType !== undefined
}

1
너무 장황하다. 비교는 이미 부울을 반환합니다 :return typeof entity === 'object' && typeof entity.nodeType !== undefined;
HTMLGuy

1
매우 흥미로운! 때로는 귀하 object및 / 또는 poperties 에있는 유형에 따라 매우 유용 할 수 있습니다! Tx, @Roman
Pedro Ferreira

3
var IsPlainObject = function ( obj ) { return obj instanceof Object && ! ( obj instanceof Function || obj.toString( ) !== '[object Object]' || obj.constructor.name !== 'Object' ); },
    IsDOMObject = function ( obj ) { return obj instanceof EventTarget; },
    IsDOMElement = function ( obj ) { return obj instanceof Node; },
    IsListObject = function ( obj ) { return obj instanceof Array || obj instanceof NodeList; },

// 사실이 인라인을 사용하지 않을 가능성이 높지만 설치 코드에 대한 단축키를 사용하는 것이 좋습니다


IE에서는 함수에 name 속성이 없으므로 obj.constructor.name은 IE에서 작동하지 않습니다. obj.constructor! = Object로 교체하십시오.
mathheadinclouds 2012 년

3

도움이 될 수 있습니다 : 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);
}

위의 코드에서, 우리는 사용하는 이중 부정 의 활용 인수로 전달 된 객체의 부울 값을 얻기 위해 운영자, 우리는 조건문에서 평가 각 표현식은 부울 수 있도록 이러한 방법으로, 단락 회로 평가 하여, 기능을 반품 true또는false


거짓이 있으면 부울을 단락시켜야합니다. 예를 들어 undefined && window.spam("should bork")가짜 spam기능을 평가하지 않습니다 . 그래서 !!필요하지 않습니다, 나는 믿지 않습니다. 즉, 사용이 중요한 [비 학술적] 엣지 케이스를 제공 할 수 있습니까?
ruffin

귀하의 성명에 감사드립니다. 나는 * !! * 이중 부정 을 사용하여 모든 표현을 진실하거나 거짓이 아닌 부울 값으로 변환했습니다.
jherax

네,하지만 그것을 할 실질적인 이유가 없다, 나는 생각하지 않는다 - 참조 여기에 . 그리고 여기서 Short-Cut eval을 활용할 필요는 없습니다. " !!필요하지 않다"라는 주장을 사지 않았더라도 ( 그렇지 않다면 왜 궁금하지 않은지 궁금하다 ), 해당 행을 편집 return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);하여 동일하게 작동시킬 수있다.
ruffin

그것이 내가 한 일이었습니다.) 더 깨끗하고 동일한 효과. 감사합니다.
jherax

2

해당 객체 또는 노드가 문자열 유형을 반환하는지 확인할 수 있습니다.

typeof (array).innerHTML === "string" => false
typeof (object).innerHTML === "string" => false
typeof (number).innerHTML === "string" => false
typeof (text).innerHTML === "string" => false

//any DOM element will test as true
typeof (HTML object).innerHTML === "string" => true
typeof (document.createElement('anything')).innerHTML === "string" => true

3
typeof ({innerHTML: ""}).innerHTML === "string"
Qtax

뜨거운! 이 응답은 게임 승자가되어야합니다. if (typeof obj.innerHTML! == 'string') // dom 요소가 아닙니다.
user3751385

1
나는 초기에 @Qtax와 thomasrutter의 비판에 대해 초기 답변에 대해 반응 했지만 그것을 사기 시작했습니다. 이전에 이와 같이 오리처럼 떨리는 개를 만난 적이 없지만 누군가 노드인지 확인하지 않고 실행 notANode.innerHTML = "<b>Whoops</b>";한 다음 나중에 해당 코드가 오염 된 obj를 코드에 전달하도록 합니다. 방어 코드 === 더 나은 코드, 다른 모든 것들은 동일하며, 이것은 궁극적으로 방어 적이 지 않습니다.
ruffin


2

프로토 타이핑은 그다지 좋은 해결책은 아니지만 아마도 가장 빠른 해결책이라고 생각합니다.이 코드 블록을 정의하십시오.

Element.prototype.isDomElement = true;
HTMLElement.prototype.isDomElement = true;

객체 isDomElement 속성을 확인하는 것보다 :

if(a.isDomElement){}

이게 도움이 되길 바란다.


1
1) 소유하지 않은 개체를 변경하는 것은 좋지 않습니다. 2) 이것은 같은 문서에 속하지 않은 요소를 감지하지 못합니다.
fregante

2

mdn 에 따르면

Element는 모든 객체가 Document상속 되는 가장 일반적인 기본 클래스입니다 . 모든 종류의 요소에 공통적 인 메소드와 속성 만 있습니다.

isElement프로토 타입으로 구현할 수 있습니다 . 내 조언은 다음과 같습니다.

/**
 * @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


1

나는 당신이해야 할 일은 항상 dom 요소에있을 일부 속성을 철저히 확인하는 것이지만 그 조합은 다른 객체에 있을 가능성거의 없습니다 .

var isDom = function (inp) {
    return inp && inp.tagName && inp.nodeName && inp.ownerDocument && inp.removeAttribute;
};

1

Firefox에서는을 사용할 수 있습니다 instanceof Node. 이는 DOM1에Node 정의되어 있습니다.

그러나 IE에서는 그렇게 쉽지 않습니다.

  1. "ActiveX의 인스턴스"는 그것이 기본 객체임을 알 수 있습니다.
  2. "typeof document.body.appendChild == 'object'"는 DOM 객체 일 수도 있지만 동일한 기능을 가진 다른 객체 일 수도 있습니다.

DOM 함수를 사용하여 DOM 요소인지 확인하고 예외가 있으면 catch 할 수 있습니다. 그러나 부작용이있을 수 있습니다 (예 : 객체 내부 상태 / 성능 / 메모리 누수 변경)


1

아마도 이것이 대안입니까? Opera 11, FireFox 6, Internet Explorer 8, Safari 5 및 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;
}

기능은 예를 들어 이것으로 속지 않을 것입니다

isDOMNode( {'nodeName':'fake'} ); // returns false

2
시도는 좋지만 예외 처리는 피할 수 있으면 비용이 너무 비쌉니다. 또한 ES5를 사용하면 객체에 대한 읽기 전용 속성을 정의 할 수 있습니다.
Andy E

1

이것이 내가 알아 낸 것입니다.

var isHTMLElement = (function () {
    if ("HTMLElement" in window) {
        // Voilà. Quick and easy. And reliable.
        return function (el) {return el instanceof HTMLElement;};
    } else if ((document.createElement("a")).constructor) {
        // We can access an element's constructor. So, this is not IE7
        var ElementConstructors = {}, nodeName;
        return function (el) {
            return el && typeof el.nodeName === "string" &&
                 (el instanceof ((nodeName = el.nodeName.toLowerCase()) in ElementConstructors 
                    ? ElementConstructors[nodeName] 
                    : (ElementConstructors[nodeName] = (document.createElement(nodeName)).constructor)))
        }
    } else {
        // Not that reliable, but we don't seem to have another choice. Probably IE7
        return function (el) {
            return typeof el === "object" && el.nodeType === 1 && typeof el.nodeName === "string";
        }
    }
})();

성능을 향상시키기 위해 브라우저 기능을 한 번만 테스트하고 그에 따라 적절한 기능을 할당하는 자체 호출 기능을 작성했습니다.

첫 번째 테스트는 대부분의 최신 브라우저에서 작동하며 여기에서 이미 논의되었습니다. 요소가의 인스턴스인지 테스트합니다 HTMLElement. 매우 간단합니다.

두 번째는 가장 흥미로운 것입니다. 이것이 핵심 기능입니다.

return el instanceof (document.createElement(el.nodeName)).constructor

el이 가장 한 구성의 인스턴스인지 테스트합니다. 그렇게하려면 요소의 생성자에 액세스해야합니다. 이것이 우리가 if 문에서 이것을 테스트하는 이유입니다. 예를 들어 IE7에 있기 때문에 IE7 (document.createElement("a")).constructor은 이것을 실패합니다 undefined.

이 방법의 문제점 document.createElement은 실제로 가장 빠른 기능이 아니며 많은 요소를 테스트하는 경우 응용 프로그램 속도를 쉽게 늦출 수 있다는 것입니다. 이를 해결하기 위해 생성자를 캐시하기로 결정했습니다. 객체 ElementConstructors는 nodeNames를 키로 사용하고 해당 생성자를 값으로 사용합니다. 생성자가 이미 캐시 된 경우 캐시에서 생성자를 사용합니다. 그렇지 않으면 요소를 작성하고 나중에 액세스 할 수 있도록 생성자를 캐시 한 다음 이에 대해 테스트합니다.

세 번째 테스트는 불쾌한 폴백입니다. el이 object이고 nodeType속성이로 설정되어 1있고 문자열이로 설정되어 있는지 테스트합니다 nodeName. 물론 이것은 신뢰할 만하지는 않지만 대다수의 사용자는 지금까지 다시 넘어서는 안됩니다.

이것은 가능한 한 성능을 계속 유지하면서 내가 찾은 가장 신뢰할만한 접근법입니다.


1

Nodeobj 에서 상속 되는지 테스트하십시오 .

if (obj instanceof Node){
    // obj is a DOM Object
}

노드는 HTMLElement와 Text를 상속 하는 기본 인터페이스 입니다.


1

원시 js 객체를 HTMLElement와 차별화

function isDOM (x){
     return /HTML/.test( {}.toString.call(x) );
 }

사용하다:

isDOM( {a:1} ) // false
isDOM( document.body ) // true

// 또는

Object.defineProperty(Object.prototype, "is",
    {
        value: function (x) {
            return {}.toString.call(this).indexOf(x) >= 0;
        }
    });

사용하다:

o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true


0

jQuery를 사용하는 트릭이 있습니다.

var obj = {};
var element = document.getElementById('myId'); // or simply $("#myId")

$(obj).html() == undefined // true
$(element).html() == undefined // false

그래서 함수에 넣으십시오.

function isElement(obj){

   return (typeOf obj === 'object' && !($(obj).html() == undefined));

}

2
jQuery는 내부적으로 그렇게 elem.nodeType === 1하므로 호출 오버 헤드와 jQuery 종속성을 저장하고 isElement 함수가 자체적으로 수행하지 않는 이유는 무엇입니까?
Joseph Lennox

2016 년입니다. "아니요"라고 말합니다.
Thomas McCabe

0

ES5 호환 브라우저 외에 다른 것들을 망치지 말고 다음과 같은 이유는 무엇입니까?

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

TextNodes에서 작동하지 확인 등 그림자 DOM 또는 DocumentFragments 약하지만하지 않음 것이다 거의 모든 HTML 태그 요소에 작동합니다.


0

이것은 거의 모든 브라우저에서 작동합니다. (여기서 요소와 노드를 구별하지 않음)

function dom_element_check(element){
    if (typeof element.nodeType !== 'undefined'){
        return true;
    }
    return false;
}

우선, true 또는 false를 반환 할 필요는 없으며 if 문만 반환하면됩니다. 둘째, {nodeType : 1}에 대해 true를 반환합니다.
bluejayke

코드의 의도를 명확하게하기 위해 지나치게 자세한 코드 (이 사이트에서)를 사용하는 경향이 있습니다.)
Zv_oDD

0

절대적으로 올바른 방법, 검사 대상은 실제 html 요소 기본 코드입니다.

    (function (scope) {
        if (!scope.window) {//May not run in window scope
            return;
        }
        var HTMLElement = window.HTMLElement || window.Element|| function() {};

        var tempDiv = document.createElement("div");
        var isChildOf = function(target, parent) {

            if (!target) {
                return false;
            }
            if (parent == null) {
                parent = document.body;
            }
            if (target === parent) {
                return true;
            }
            var newParent = target.parentNode || target.parentElement;
            if (!newParent) {
                return false;
            }
            return isChildOf(newParent, parent);
        }
        /**
         * The dom helper
         */
        var Dom = {
            /**
             * Detect if target element is child element of parent
             * @param {} target The target html node
             * @param {} parent The the parent to check
             * @returns {} 
             */
            IsChildOf: function (target, parent) {
                return isChildOf(target, parent);
            },
            /**
             * Detect target is html element
             * @param {} target The target to check
             * @returns {} True if target is html node
             */
            IsHtmlElement: function (target) {
                if (!X.Dom.IsHtmlNode(target)) {
                    return false;
                }
                return target.nodeType === 1;
            },
            /**
             * Detect target is html node
             * @param {} target The target to check
             * @returns {} True if target is html node
             */
            IsHtmlNode:function(target) {
                if (target instanceof HTMLElement) {
                    return true;
                }
                if (target != null) {
                    if (isChildOf(target, document.documentElement)) {
                        return true;
                    }
                    try {
                        tempDiv.appendChild(target.cloneNode(false));
                        if (tempDiv.childNodes.length > 0) {
                            tempDiv.innerHTML = "";
                            return true;
                        }
                    } catch (e) {

                    }
                }
                return false;
            }
        };
        X.Dom = Dom;
    })(this);

IE 5에서 테스트


0

DOMElement.constructorHTML ... Element () 또는 [Object HTML ... Element] 함수를 반환 합니다 .

function isDOM(getElem){
    if(getElem===null||typeof getElem==="undefined") return false;
    var c = getElem.constructor.toString();
    var html = c.search("HTML")!==-1;
    var element = c.search("Element")!==-1;
    return html&&element;
}

0

답변에 아직 언급되지 않은 특별한 방법이 있습니다.

내 솔루션은 네 가지 테스트를 기반으로합니다. 객체가 네 개를 모두 통과하면 요소입니다.

  1. 객체가 null이 아니다

  2. 이 개체에는 "appendChild"라는 메서드가 있습니다.

  3. "appendChild"메소드는 Node 클래스 에서 상속되었으며 단순한 임 포스터 메소드 (같은 이름의 사용자 작성 특성)가 아닙니다.

  4. 오브젝트는 노드 유형 1 (요소)입니다. Node 클래스 에서 메소드를 상속받는 객체 는 항상 노드이지만 반드시 요소는 아닙니다.

Q : 주어진 속성이 상속되고 단순한 사기가 아닌지 어떻게 확인합니까?

A : 메소드가 Node 에서 실제로 상속 되었는지 확인 하는 간단한 테스트 는 먼저 속성에 "object"또는 "function"유형이 있는지 확인하는 것입니다. 그런 다음 속성을 문자열로 변환하고 결과에 "[Native Code]"텍스트가 포함되어 있는지 확인하십시오. 결과가 다음과 같은 경우 :

function appendChild(){
[Native Code]
}

그런 다음 메소드는 Node 객체에서 상속되었습니다. 참조 https://davidwalsh.name/detect-native-function를

마지막으로 모든 테스트를 종합하면 솔루션은 다음과 같습니다.

function ObjectIsElement(obj) {
    var IsElem = true;
    if (obj == null) {
        IsElem = false;
    } else if (typeof(obj.appendChild) != "object" && typeof(obj.appendChild) != "function") {
        //IE8 and below returns "object" when getting the type of a function, IE9+ returns "function"
        IsElem = false;
    } else if ((obj.appendChild + '').replace(/[\r\n\t\b\f\v\xC2\xA0\x00-\x1F\x7F-\x9F ]/ig, '').search(/\{\[NativeCode]}$/i) == -1) {
        IsElem = false;
    } else if (obj.nodeType != 1) {
        IsElem = false;
    }
    return IsElem;
}

0
(element instanceof $ && element.get(0) instanceof Element) || element instanceof Element

jQuery 또는 JavaScript DOM 요소 인 경우에도 확인합니다.


0

HTML 요소와 동일한 속성을 가진 객체뿐만 아니라 실제 HTMLEement를 확인하는 유일한 방법은 JavaScript에서 새 Node ()를 만들 수 없기 때문에 Node에서 상속되는지 여부를 확인하는 것입니다. (기본 노드 기능을 덮어 쓰지 않는 한 운이 좋지 않습니다). 그래서:

function isHTML(obj) {
    return obj instanceof Node;
}

console.log(
  isHTML(test),
  isHTML(ok),
  isHTML(p),
  isHTML(o),
  isHTML({
    constructor: {
      name: "HTML"
    }
  }),
  isHTML({
    __proto__: {
      __proto__: {
        __proto__: {
          __proto__: {
            constructor: {
              constructor: { 
                name: "Function"
                
              },
              name: "Node"
            }
          }
        }
      }
    }
  }),
)
<div id=test></div>
<blockquote id="ok"></blockquote>
<p id=p></p>
<br id=o>
<!--think of anything else you want--!>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.