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

나는 노력하고있다 :

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

좋은 대체물이 있습니까?



답변

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

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


답변

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

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

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

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


답변

위와 아래의 모든 솔루션 (내 솔루션 포함)은 특히 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각각을 반환해야합니다 . 메소드를 테스트하는 유일한 방법은 메소드가 정의되어 있는지 확인하는 것입니다.


답변

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

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

    return true;
}


답변

해킹이 필요하지 않습니다. 요소가 DOM 요소 의 인스턴스인지 물어볼 수 있습니다 .

const isDOM = el => el instanceof Element


답변

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

$ npm install lodash.iselement

그리고 코드에서 :

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


답변

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

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