Bir JavaScript Nesnesinin DOM Nesnesi olup olmadığını nasıl kontrol edersiniz?


248

Ben almaya çalışıyorum:

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

Kendi komut dosyalarında, tagNamebir özellik olarak hiç ihtiyaç duymadığım için bunu kullanıyordum :

if (!object.tagName) throw ...;

İkinci nesne için, çoğunlukla işe yarayan hızlı bir çözüm olarak aşağıdakileri buldum. ;)

Sorun, hepsi değil, salt okunur özellikleri zorlayan tarayıcılara bağlıdır.

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

İyi bir yedek var mı?


3
Bir "DOM Nesnesi" nin yalnızca Öğeleri değil tüm Düğümleri de (Metin düğümleri, Nitelikler, vb.) Kapsaması gerekip gerekmediğini merak ediyor muyum? Tüm cevaplar ve soruyu sorma şekliniz bu sorunun özellikle Elements ile ilgili olduğunu söyleme eğilimindedir ...
mike rodent

Yanıtlar:


300

Bu ilgi çekici olabilir:

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'nin bir parçası , Level2 .

Güncelleme 2 : Kendi kütüphanemde bu şekilde uyguladım: (önceki kod Chrome'da çalışmadı, çünkü Düğüm ve HTMLElement beklenen nesne yerine işlevler. Bu kod FF3, IE7, Chrome 1 ve Opera'da test edildi 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
Bunun diğer pencerelere / çerçevelere ait öğeler üzerinde çalışmayacağını belirtmek gerekir. Ördek yazması önerilen yaklaşımdır
Andy E

2
Şunu kandırabilirsin:function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
Çekirdek James

11
WTF gerçek: Firefox 5 ve daha önceki dönüş trueiçin [] instanceof HTMLElement.
Rob W

6
Btw, HTMLElementher zaman bir function, bu yüzden typeofsizi pist dışına atar ve ifadenin ikinci bölümünü yürütür. İsterseniz deneyebilirsiniz instanceof Objectfonksiyonu bir örneği olur çünkü, Objectya da sadece için açıkça kontrol typeof === "function", çünkü Nodeve HTMLElementher ikisi yerli nesne fonksiyonları bulunmaktadır.
Roland

2
Aradığınızda isElement(0), yanlış değil 0 döndürür ... Neden bu ve bunu nasıl önleyebilirim?
Jessica

68

Aşağıdaki IE8 uyumlu, süper basit kod mükemmel çalışır.

Kabul edilen cevap her tür HTML öğesini algılamaz. Örneğin, SVG öğeleri desteklenmez. Buna karşılık, bu cevap HTML için olduğu kadar SVG için de geçerlidir.

Burada iş başında görün: https://jsfiddle.net/eLuhbu6r/

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

3
'Element' IE7'de tanımlanmadı
Dan

49
Ben hala IE7 kullanan herkesin daha iyi bir tarayıcı indirmek için beş saniye harcamak yerine bize zamanları almak için reddetme etrafında çalışma gün veya hafta yatırım yapmak yerine harcamak gerektiğini düşünüyorum.
mopsyd

1
Ben mopsyd ile hemfikirim, ancak cevabın yazarı, doğruluk uğruna güncellenmesi gerekebilecek IE7'de çalıştığını belirtiyor.
Lajos Meszaros

1
IE9 demek için güncellendi. IE8'in destekleyip desteklemediğinden emin değilim.
Monarch Wadia

1
@MonarchWadia evet IE8'de desteklenir. Ancak bunun, documentöğe için (tüm tarayıcılarda) true döndürmediğini unutmayın . Eğer ihtiyacınız varsa, denemelisiniz:x instanceof Element || x instanceof HTMLDocument
S.Serpooshan

11

Yukarıdaki ve aşağıdaki tüm çözümler (benim çözümüm dahil) özellikle IE'de yanlış olma olasılığından muzdariptir - testi geçersiz kılan bir DOM düğümünü taklit etmek için bazı nesneleri / yöntemleri / özellikleri tanımlamak (yeniden) mümkündür.

Bu yüzden genellikle ördek yazma tarzı testi kullanıyorum: Özellikle kullandığım şeyler için test ediyorum. Örneğin, bir düğümü klonlamak isterseniz bunu şöyle test ederim:

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

Temelde biraz akıl sağlığı kontrol + kullanmayı planlıyorum bir yöntem (veya bir özellik) için doğrudan test.

Bu arada, yukarıdaki test tüm tarayıcılardaki DOM düğümleri için iyi bir testtir. Ancak güvenli tarafta olmak istiyorsanız, her zaman yöntemlerin ve özelliklerin varlığını kontrol edin ve türlerini doğrulayın.

EDIT: IE, düğümleri temsil etmek için ActiveX nesnelerini kullanır, bu nedenle özellikleri gerçek JavaScript nesnesi gibi davranmaz, örneğin:

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

buna karşılık "işlev" ve truesırasıyla dönmelidir . Yöntemleri test etmenin tek yolu tanımlı olup olmadıklarını görmektir.


"typeof document.body.cloneNode", IE'de "nesne" döndürüyor
Dennis C

Bu iyi bir cevap gibi görünüyor. Aşağıdaki
yanıtıma

8

Gerçek bir DOM düğümüne eklemeyi deneyebilirsiniz ...

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

    return true;
}

11
Bu çalışıyor mu? Hala bir çözüm. Yaratıcı bir tane.
Justin Meyer

3
Bu yaratıcılık ve kesinlik için +1. Ancak, düğüm zaten DOM'un bir parçasıysa, kaldırdınız! Yani ... bu cevap, gerekirse öğeyi DOM'a yeniden eklemek için çalışma yapmadan tamamlanmamıştır.
svidgen

4
Bunu neredeyse 5 yıl sonra okuyorum ve bence en havalı olanlardan biri. Sadece rafine edilmesi gerekiyor. Örneğin, ayrılmış bir öğeye düğümün bir klonunu eklemeyi deneyebilirsiniz . Bu bir DOM nesnesi değilse. bir şeyler mutlaka yanlış gidecek. Yine de oldukça pahalı bir çözüm.
MaxArt

Veya bunun yerine eklemek çalışmakla klonu , elemanın sadece klonlamak için çalışıyor yeterli olacaktır: obj.cloneNode(false). AND'in hiçbir yan etkisi yoktur.
mauroc8

1
Bu gerçekten pahalı ve gereksiz yere karmaşık. Aşağıdaki cevabımı görün, stackoverflow.com/a/36894871/1204556
Monarch Wadia


6

Lo-Dash'e_.isElement ne dersin ?

$ npm install lodash.iselement

Ve kodda:

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

1
Bu çözümü seviyorum. Bu basittir ve Edge ve IE'de, en yüksek oy alan çözümlerin çoğunun aksine, ayrı iframe'lerdeki öğeler için bile çalışır.
Elias Zamaria

Bu cevap yararlıdır, ancak tarayıcıda NPM modüllerini çalıştırmak için Webpack'e ihtiyaç duyulacaktır.
Edwin Pratt

5

Bu güzel JavaScript kütüphanesi MooTools'tan :

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

12
Bu kod, nesnenin bir DOM öğesi olduğunu iddia etmez; sadece biraz benziyor. Herhangi bir nesneye bir nodeName ve nodeType özelliği verilebilir ve bu kodu karşılayabilir.
thomasrutter

Bu yanıt, tüm HTML öğeleri türlerini algılamaz. Örneğin, SVG öğeleri desteklenmez. Cevabımı aşağıda görebilirsiniz.
Monarch Wadia

SVG gibi tüm öğeler üzerinde gerçekten çalışmaz. Aşağıdaki cevabımı görün, stackoverflow.com/a/36894871/1204556
Monarch Wadia

4

Burada bulunan kök algılamayı kullanarak, örneğin uyarının nesnenin kökünün bir üyesi olup olmadığını belirleyebiliriz , bu da daha sonra bir pencere olur:

function isInAnyDOM(o) { 
  return (o !== null) && !!(o.ownerDocument && (o.ownerDocument.defaultView || o.ownerDocument.parentWindow).alert); // true|false
}

Nesnenin geçerli pencere olup olmadığını belirlemek için daha da basittir:

function isInCurrentDOM(o) { 
  return (o !== null) && !!o.ownerDocument && (window === (o.ownerDocument.defaultView || o.ownerDocument.parentWindow)); // true|false
}

Bu, açma ipliğindeki dene / yakala çözümünden daha ucuzdur.

Don P


Bunu en son Chrome ve FF'de ve ayrıca IE11'de test ettim ve her yerde, metin düğümleri ve document.createElement()DOM yoluyla oluşturulan ancak DOM'a eklenmeyen nesneler için de çalışıyor . Şaşırtıcı (: Teşekkür ederim
Geradlus_RU

Benimki aynı şeyleri yapıyor ve daha az karmaşık olsa da, bu iyi bir cevap gibi görünüyor. stackoverflow.com/a/36894871/1204556
Monarch Wadia

4

eski konu, ancak burada ie8 ve ff3.5 kullanıcıları için güncellenmiş bir olasılık :

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

4

Bir değişkenin DOM öğesi olup olmadığını test etmenin basit bir yolunu öneririm

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

veya HTMLGuy'un önerdiği gibi:

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

1
Çok ayrıntılı. Karşılaştırma zaten bir boole döndürecek:return typeof entity === 'object' && typeof entity.nodeType !== undefined;
HTMLGuy

1
Çok ilginç! Bazen, objects ve / veya poperties üzerinde sahip olduğunuz Türlere bağlı olarak, bu çok kullanışlı olabilir! 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; },

// Aslında bu satır içi kullanımı daha olası değilim, ancak bazen kurulum kodu için bu kısayollara sahip olmak iyi olur


obj.constructor.name IE'de çalışmaz, çünkü IE'de işlevler name özelliğine sahip değildir. Obj.constructor! = Object ile değiştirin.
mathheadinclouds

3

Bu yardımcı olabilir: 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);
}

Yukarıdaki kodda, kullandığımız çift olumsuzlaması yararlanarak argüman olarak geçen nesnenin boole değeri elde etmek için operatör, koşullu açıklamada değerlendirilen her sentezleme boole sağlamak bu şekilde, kısa devre Değerlendirilmesi Bu şekilde, işlev döner trueveyafalse


Yanlış olan herhangi bir şey boolean'ınıza kısa devre yapmalıdır. Örneğin undefined && window.spam("should bork"), sahte spamişlevi asla değerlendirmez . Yani gerek yok !!, inanmıyorum. Bu, kullanımının önemli olduğu bir [akademik olmayan] uç dava sunabilir misiniz?
ruffin

Beyanınız için teşekkür ederim. Kullandığım * !! * çift olumsuzlamasıydı mantıksal değer değil truthy veya falsy tüm ifadeyi dönüştürün.
jherax

Doğru, ama bunu yapmak için pratik bir neden yok, sanmıyorum - buraya bakın . Ve burada Kısayol değerlendirmesinden yararlanmak kesinlikle gerekli değildir. " !!Asla ihtiyaç duyulmaz" argümanını satın almasanız bile ( ve yapmıyorsanız nedenini merak etmiyorum ), bu satırı düzenleyebilir return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);ve aynı şekilde çalıştırabilirsiniz.
ruffin

Yaptığım buydu;) daha temiz ve aynı etki. teşekkür ederim.
jherax

2

Söz konusu nesnenin veya düğümün bir dize türü döndürüp döndürmediğini görebilirsiniz.

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

SICAK! Bu yanıt oyunun galibi olmalıdır. if (typeof obj.innerHTML! == 'string') // bir dom öğesi değil.
user3751385

1
Başlangıçta @ Qtax ve thomasrutter'ın eleştirilerine daha erken bir cevap verdim, ama almaya başladım. Daha önce tam olarak böyle ördek gibi quacking köpekler çalıştırmak değil rağmen bir şey çalışan bir düğüm ise, birisi kontrol etmiyor görebilirsiniz notANode.innerHTML = "<b>Whoops</b>";daha sonra bu kodun için obj kirlenmiş geçmesi sahip bu kodun. Savunma kodu === daha iyi kod, diğer her şey eşittir ve bu sonuçta savunma değildir.
ruffin


2

Ben prototip çok iyi bir çözüm değil ama belki de bu en hızlı olanı düşünüyorum: Bu kod bloğunu tanımlayın;

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

isDomElement özelliğinizi kontrol etmekten ziyade:

if(a.isDomElement){}

Umarım bu yardımcı olur.


1
1) sahibi olmadığınız nesneleri değiştirmek tavsiye edilmez. 2) bu, aynı belgenin parçası olmayan öğeleri algılamaz.
fregante

2

MDN'ye göre

Elementtüm nesnelerin Documentmiras aldığı en genel temel sınıftır . Sadece her türlü eleman için ortak olan yöntem ve özelliklere sahiptir.

isElementPrototip ile uygulayabiliriz . İşte tavsiyem:

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

Yapmanız gereken, her zaman bir dom öğesinde olacak bazı özellikleri ayrıntılı bir şekilde kontrol etmek olduğunu düşünüyorum, ancak bunların kombinasyonu büyük olasılıkla başka bir nesnede olmayacak:

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

1

Firefox'ta instanceof Node,. Bu DOM1'deNode tanımlanır .

Ama bu IE'de o kadar kolay değil.

  1. "instanceof ActiveXObject" yalnızca yerel bir nesne olduğunu söyleyebilir.
  2. "typeof document.body.appendChild == 'object'", bunun DOM nesnesi olabileceğini, ancak aynı işlevi olan başka bir şey olabileceğini söyler.

Yalnızca DOM işlevini kullanarak DOM öğesi olduğundan emin olabilir ve herhangi bir istisna varsa yakalayabilirsiniz. Ancak, yan etkisi olabilir (örneğin, nesnenin dahili durumunu / performansını / bellek sızıntısını değiştirme)


1

Belki de bu bir alternatiftir? Opera 11, FireFox 6, Internet Explorer 8, Safari 5 ve Google Chrome 16'da test edildi.

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

İşlev bu şekilde kandırılmayacak

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

2
İyi deneyin, ancak istisna işleme, önlenebilirse çok pahalıdır. Ayrıca, ES5 nesneler için salt okunur özellikler tanımlamanızı sağlar.
Andy E

1

Ben bunu anladım:

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

Performansı artırmak için, tarayıcının yeteneklerini yalnızca bir kez test eden ve buna göre uygun işlevi atayan kendi kendini çağıran bir işlev oluşturdum.

İlk test çoğu modern tarayıcıda çalışmalıdır ve burada zaten tartışılmıştır. Sadece öğenin bir örneği olup olmadığını test eder HTMLElement. Çok basit.

İkincisi en ilginç olanı. Temel işlevi:

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

El'in, varmış gibi görünen yapının bir örneği olup olmadığını test eder. Bunu yapmak için bir elemanın yapıcısına erişmemiz gerekir. Bu yüzden if-Deyiminde bunu test ediyoruz. Çünkü örneğin IE7, bu başarısız (document.createElement("a")).constructorolduğu undefinedIE7'de.

Bu yaklaşımdaki sorun document.createElement, gerçekten en hızlı işlev olmaması ve çok sayıda öğeyi test ediyorsanız uygulamanızı yavaşlatabilmesidir. Bunu çözmek için yapıcıları önbelleğe almaya karar verdim. Nesnenin ElementConstructorsanahtarları olarak nodeNames, karşılık gelen kurucuları değer olarak içerir. Bir kurucu zaten önbelleğe alınmışsa, onu önbellekten kullanır, aksi takdirde Öğe'yi oluşturur, yapıcısını gelecekteki erişim için önbelleğe alır ve sonra buna karşı test eder.

Üçüncü test tatsız düşüştür. El'in bir object, bir nodeTypeözelliği 1ve bir dize olarak ayarlanmış olup olmadığını test eder nodeName. Bu elbette çok güvenilir değil, ancak kullanıcıların büyük çoğunluğu şimdiye kadar geri çekilmemeli.

Performansı mümkün olduğunca yüksek tutarken ortaya koyduğum en güvenilir yaklaşım budur.


1

Düğümdenobj miras alıp almadığını test edin .

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

Düğüm bir temel Arayüz hangi HTMLElement ve Metin devralır gelen.


1

ham js nesnesini HTMLElement öğesinden ayırt etme

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

kullanın:

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

// VEYA

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

kullanın:

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


0

İşte jQuery kullanarak bir hile

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

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

böylece bir işleve koymak:

function isElement(obj){

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

}

2
jQuery dahili yapıyor elem.nodeType === 1bu yüzden neden çağrı yükü ve jQuery bağımlılığı kaydetmek ve isElement işlevi bunu kendisi yapmak değil?
Joseph Lennox

2016, sadece "hayır" deyin.
Thomas McCabe

0

Bu veya başka bir şeye dayanmak değil, ES5 uyumlu tarayıcılar için neden sadece:

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

TextNodes üzerinde çalışmak ve emin vb Gölge DOM veya DocumentFragments ilgili değil ama olmaz edecektir hemen hemen tüm HTML etiket öğelerini üzerinde çalışmak.


0

Bu hemen hemen her tarayıcıda işe yarar. (Burada elementler ve düğümler arasında ayrım yok)

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

her şeyden önce, doğru döndürmeniz veya yanlış döndürmeniz gerekmez, if ifadesini döndürmeniz yeterlidir. İkinci olarak, bu {nodeType: 1} için dönecektir
bluejayke

Ben kod niyetini daha açık yapmak amacıyla (bu sitede) aşırı ayrıntılı kod kullanma eğilimindedir;)
Zv_oDD

0

Mutlak bir doğru yöntem, kontrol hedefi gerçek bir html öğesi birincil kodudur:

    (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'de Test


0

Her DOMElement.constructor işlevi HTML ... Element () veya [Object HTML ... Element] işlevini döndürür ...

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

Bunu cevaplarda henüz belirtilmeyen özel bir yolum var.

Benim çözümüm dört testten oluşuyor. Nesne dördünü de geçerse, bu bir öğedir:

  1. Nesne boş değil.

  2. Nesnenin "appendChild" adlı bir yöntemi vardır.

  3. "AppendChild" yöntemi, Node sınıfından miras alındı ve yalnızca bir imposter yöntemi (aynı adlı bir kullanıcı tarafından oluşturulan özellik) değil.

  4. Nesne Düğüm Türü 1'dir (Öğe). Düğüm sınıfından yöntemleri devralan nesneler her zaman Düğümdür, ancak zorunlu olarak Öğeler değildir.

S: Belirli bir mülkün miras alındığını ve sadece bir sahtekarlık olmadığını nasıl kontrol edebilirim?

C: Bir yöntemin Düğümden gerçekten miras alınıp alınmadığını görmek için basit bir test , öncelikle özelliğin bir tür "nesne" veya "işlev" olduğunu doğrulamaktır. Ardından, özelliği bir dizeye dönüştürün ve sonucun "[Yerel Kod]" metnini içerip içermediğini kontrol edin. Sonuç şöyle görünürse:

function appendChild(){
[Native Code]
}

Sonra yöntem Düğüm nesnesinden devralındı. Bkz. Https://davidwalsh.name/detect-native-function

Ve son olarak, tüm testleri bir araya getiren çözüm:

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

Bu, bir jQuery veya JavaScript DOM öğesi olsa bile kontrol eder


0

Yalnızca HTML Öğesi ile aynı özelliklere sahip bir nesne değil, gerçek bir HTMLEement'i kontrol ettiğinizden emin olmanın tek yolu, JavaScript'te yeni bir Düğüm () yapmak imkansız olduğu için Düğümden miras alıp almadığını belirlemektir. (yerel Düğüm işlevinin üzerine yazılmazsa, ancak şansınız kalmazsa). Yani:

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--!>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.