Saya mencoba untuk mendapatkan:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
Dalam skrip saya sendiri, saya biasa menggunakan ini karena saya tidak pernah membutuhkan tagName
sebagai properti:
if (!object.tagName) throw ...;
Jadi untuk objek kedua, saya datang dengan yang berikut sebagai solusi cepat - yang kebanyakan berhasil. ;)
Masalahnya adalah, itu tergantung pada browser yang memberlakukan properti read-only, yang tidak semuanya melakukannya.
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;
}
}
Apakah ada pengganti yang bagus?
javascript
dom
object
Jonathan Lonowski
sumber
sumber
Jawaban:
Ini mungkin menarik:
Itu bagian dari DOM, Level2 .
Pembaruan 2 : Ini adalah cara saya menerapkannya di perpustakaan saya sendiri: (kode sebelumnya tidak berfungsi di Chrome, karena Node dan HTMLElement adalah fungsi alih-alih objek yang diharapkan. Kode ini diuji dalam FF3, IE7, Chrome 1 dan Opera 9).
sumber
function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
true
untuk[] instanceof HTMLElement
.HTMLElement
selalu afunction
, jaditypeof
akan membuat Anda keluar jalur dan akan menjalankan bagian kedua dari pernyataan itu. Anda dapat mencoba jika Anda mauinstanceof Object
, karena fungsi akan menjadi instanceObject
, atau hanya memeriksa secara eksplisittypeof === "function"
, karenaNode
danHTMLElement
keduanya fungsi objek asli.isElement(0)
, ia mengembalikan 0, bukan salah ... Mengapa begitu, dan bagaimana saya bisa mencegahnya?Kompatibel dengan IE8 berikut, kode super sederhana bekerja dengan sempurna.
The jawaban yang diterima tidak mendeteksi semua jenis elemen HTML. Misalnya, elemen SVG tidak didukung. Sebaliknya, jawaban ini berfungsi untuk HTML dan juga SVG.
Lihat beraksi di sini: https://jsfiddle.net/eLuhbu6r/
sumber
document
elemen (di semua browser). jika Anda membutuhkannya, Anda harus mencoba:x instanceof Element || x instanceof HTMLDocument
Semua solusi di atas dan di bawah (termasuk solusi saya) menderita kemungkinan salah, terutama pada IE - sangat mungkin untuk (kembali) mendefinisikan beberapa objek / metode / properti untuk meniru node DOM yang membuat tes tidak valid.
Jadi biasanya saya menggunakan pengujian gaya mengetik bebek: Saya menguji secara khusus untuk hal-hal yang saya gunakan. Sebagai contoh, jika saya ingin mengkloning sebuah node saya mengujinya seperti ini:
Pada dasarnya ini adalah pemeriksaan kewarasan kecil + tes langsung untuk suatu metode (atau properti) yang saya rencanakan untuk digunakan.
Kebetulan tes di atas adalah tes yang baik untuk node DOM di semua browser. Tetapi jika Anda ingin berada di sisi yang aman selalu periksa keberadaan metode dan properti dan verifikasi tipenya.
EDIT: IE menggunakan objek ActiveX untuk mewakili node, jadi propertinya tidak berperilaku sebagai objek JavaScript yang sebenarnya, misalnya:
sementara itu harus mengembalikan "fungsi" dan
true
masing - masing. Satu-satunya cara untuk menguji metode adalah untuk melihat apakah sudah ditentukan.sumber
Anda dapat mencoba menambahkannya ke simpul DOM nyata ...
sumber
obj.cloneNode(false)
. DAN tidak memiliki efek samping.Tidak perlu melakukan peretasan, Anda bisa bertanya apakah sebuah elemen adalah turunan dari Elemen DOM :
sumber
Bagaimana dengan Lo-Dash
_.isElement
?Dan dalam kode:
sumber
Ini dari pustaka JavaScript yang indah MooTools :
sumber
Dengan menggunakan deteksi root yang ditemukan di sini , kita dapat menentukan apakah mis. Lansiran adalah anggota dari root objek, yang kemudian kemungkinan akan berupa jendela:
Untuk menentukan apakah objeknya adalah jendela saat ini lebih sederhana:
Ini tampaknya lebih murah daripada solusi coba / tangkap di utas pembuka.
Don P
sumber
document.createElement()
tetapi tidak dimasukkan dalam DOM juga. Luar biasa (: Terima kasihutas lama, tapi di sini ada kemungkinan yang diperbarui untuk pengguna ie8 dan ff3.5 :
sumber
Saya menyarankan cara sederhana untuk menguji apakah suatu variabel adalah elemen DOM
atau seperti yang disarankan HTMLGuy :
sumber
return typeof entity === 'object' && typeof entity.nodeType !== undefined;
object
dan / atau poperties, ini bisa sangat berguna! Tx, @Roman// Sebenarnya saya lebih cenderung menggunakan inline ini, tetapi kadang-kadang ada baiknya menggunakan pintasan ini untuk kode pengaturan
sumber
Ini bisa membantu: isDOM
Dalam kode di atas, kami menggunakan operator negasi ganda untuk mendapatkan nilai boolean dari objek yang dilewatkan sebagai argumen, dengan cara ini kami memastikan bahwa setiap ekspresi yang dievaluasi dalam pernyataan bersyarat menjadi boolean, mengambil keuntungan dari Evaluasi Sirkuit Pendek , dengan demikian fungsinya mengembalikan
true
ataufalse
sumber
undefined && window.spam("should bork")
tidak pernah mengevaluasispam
fungsi palsu , misalnya. Jadi tidak!!
perlu, saya tidak percaya. Itu, bisakah Anda memberikan kasus tepi [non-akademik] di mana penggunaannya penting?!!
argumen "tidak pernah dibutuhkan" ( dan jika tidak, saya ingin tahu kenapa tidak ), Anda dapat mengedit baris itureturn !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
dan mengoperasikannya juga.Anda dapat melihat apakah objek atau simpul yang dimaksud mengembalikan tipe string.
sumber
typeof ({innerHTML: ""}).innerHTML === "string"
notANode.innerHTML = "<b>Whoops</b>";
, lalu kemudian kode itu meneruskan objek yang terkontaminasi ke kode ini . Kode defensif === kode yang lebih baik, semua hal lainnya sama, dan ini pada akhirnya tidak defensif.Untuk yang menggunakan Angular:
https://docs.angularjs.org/api/ng/function/angular.isElement
sumber
function isElement(node) { return !!(node && (node.nodeName || (node.prop && node.attr && node.find))); }
Sepertinya sedikit seperti @ finpingvin . Perhatikan bahwa ini menentukan " apakah referensi adalah elemen DOM (atau elemen jQuery yang dibungkus). "Saya pikir prototyping bukan solusi yang sangat bagus tapi mungkin ini yang tercepat: Tentukan blok kode ini;
daripada memeriksa objek Anda properti isDomElement:
Saya harap ini membantu.
sumber
Menurut mdn
Kita dapat mengimplementasikannya
isElement
dengan prototipe. Ini saran saya:sumber
Saya pikir apa yang harus Anda lakukan adalah melakukan pemeriksaan menyeluruh atas beberapa properti yang akan selalu berada dalam elemen dom, tetapi kombinasinya kemungkinan besar tidak akan ada di objek lain, seperti:
sumber
Di Firefox, Anda dapat menggunakan
instanceof Node
. ItuNode
didefinisikan dalam DOM1 .Tapi itu tidak semudah itu di IE.
Anda hanya dapat memastikan itu adalah elemen DOM dengan menggunakan fungsi DOM dan menangkap jika ada pengecualian. Namun, itu mungkin memiliki efek samping (misalnya mengubah keadaan internal objek / kinerja / kebocoran memori)
sumber
Mungkin ini alternatif? Diuji di Opera 11, FireFox 6, Internet Explorer 8, Safari 5 dan Google Chrome 16.
Fungsi tidak akan tertipu oleh misal ini
sumber
Inilah yang saya tahu:
Untuk meningkatkan kinerja, saya membuat fungsi self-invaging yang menguji kemampuan browser hanya sekali dan menetapkan fungsi yang sesuai.
Tes pertama harus bekerja di sebagian besar browser modern dan sudah dibahas di sini. Itu hanya menguji apakah elemen tersebut adalah instance dari
HTMLElement
. Sangat mudah.Yang kedua adalah yang paling menarik. Ini adalah fungsionalitas intinya:
Ia menguji apakah el adalah turunan dari konstruktor yang dikehendaki. Untuk melakukan itu, kita perlu akses ke konstruktor elemen. Itu sebabnya kami menguji ini di if-Statement. IE7 misalnya gagal ini, karena
(document.createElement("a")).constructor
adaundefined
di IE7.Masalah dengan pendekatan ini adalah yang
document.createElement
benar-benar bukan fungsi tercepat dan dapat dengan mudah memperlambat aplikasi Anda jika Anda menguji banyak elemen dengannya. Untuk mengatasi ini, saya memutuskan untuk membuat cache konstruktor. ObjekElementConstructors
memiliki nodeNames sebagai kunci dengan konstruktor yang sesuai sebagai nilai. Jika sebuah konstruktor sudah di-cache, ia menggunakannya dari cache, jika tidak ia menciptakan Elemen, cache konstruktornya untuk akses di masa depan dan kemudian mengujinya.Tes ketiga adalah fallback yang tidak menyenangkan. Ia menguji apakah el adalah sebuah
object
, memilikinodeType
properti yang disetel1
dan string sebagainodeName
. Ini tentu saja tidak terlalu andal, namun sebagian besar pengguna seharusnya tidak mundur sejauh ini.Ini adalah pendekatan yang paling dapat diandalkan yang saya buat dengan tetap menjaga kinerja setinggi mungkin.
sumber
Tes jika
obj
mewarisi dari Node .Node adalah antarmuka dasar dari mana HTMLElement dan Teks mewarisi.
sumber
membedakan objek js mentah dari HTMLElement
menggunakan:
// ATAU
menggunakan:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
sumber
inilah trik menggunakan jQuery
jadi memasukkannya ke dalam fungsi:
sumber
elem.nodeType === 1
mengapa tidak menyimpan overhead panggilan dan ketergantungan jQuery dan apakah fungsi isElement Anda melakukannya sendiri?Bukan untuk menekankan ini atau apa pun kecuali untuk browser yang sesuai dengan ES5 mengapa tidak hanya:
Tidak akan bekerja pada TextNodes dan tidak yakin tentang Shadow DOM atau DocumentFragments dll. Tetapi akan bekerja pada hampir semua elemen tag HTML.
sumber
Ini akan berfungsi untuk hampir semua browser. (Tidak ada perbedaan antara elemen dan node di sini)
sumber
Metode benar mutlak, periksa target adalah kode primer elemen html nyata :
sumber
Setiap DOMElement.constructor mengembalikan fungsi HTML ... Element () atau [Object HTML ... Element] jadi ...
sumber
Saya punya cara khusus untuk melakukan ini yang belum disebutkan dalam jawaban.
Solusi saya didasarkan pada empat tes. Jika objek melewati keempatnya, maka itu adalah elemen:
Objeknya bukan nol.
Objek memiliki metode yang disebut "appendChild".
Metode "appendChild" diwarisi dari kelas Node , dan bukan hanya metode peniru (properti yang dibuat pengguna dengan nama yang sama).
Objeknya adalah Node Type 1 (Elemen). Objek yang mewarisi metode dari kelas Node selalu Nodes, tetapi tidak harus Elemen.
T: Bagaimana cara saya memeriksa apakah properti yang diberikan adalah warisan dan bukan hanya penipu?
A: Tes sederhana untuk melihat apakah suatu metode benar-benar diwarisi dari Node adalah untuk memverifikasi terlebih dahulu bahwa properti memiliki jenis "objek" atau "fungsi". Selanjutnya, konversi properti menjadi string dan periksa apakah hasilnya mengandung teks "[Kode Asli]". Jika hasilnya terlihat seperti ini:
Maka metode ini telah diwarisi dari objek Node. Lihat https://davidwalsh.name/detect-native-function
Dan akhirnya, menyatukan semua tes, solusinya adalah:
sumber
Ini akan memeriksa bahkan jika itu adalah elemen jQuery atau JavaScript DOM
sumber
Satu-satunya cara untuk menjamin Anda memeriksa HTMLEement yang sebenarnya, dan bukan hanya objek dengan properti yang sama dengan Elemen HTML, adalah untuk menentukan apakah itu mewarisi dari Node, karena tidak mungkin untuk membuat Node () baru di JavaScript. (kecuali fungsi Node asli ditimpa, tetapi kemudian Anda kurang beruntung). Begitu:
sumber