Bagaimana saya bisa memeriksa jika ada elemen di DOM yang terlihat?

423

Bagaimana Anda menguji elemen untuk keberadaan tanpa menggunakan getElementByIdmetode ini?

Saya telah menyiapkan demo langsung untuk referensi. Saya juga akan mencetak kode di sini juga:

<!DOCTYPE html>
<html>
<head>
    <script>
    var getRandomID = function (size) {
            var str = "",
                i = 0,
                chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
            while (i < size) {
                str += chars.substr(Math.floor(Math.random() * 62), 1);
                i++;
            }
            return str;
        },
        isNull = function (element) {
            var randomID = getRandomID(12),
                savedID = (element.id)? element.id : null;
            element.id = randomID;
            var foundElm = document.getElementById(randomID);
            element.removeAttribute('id');
            if (savedID !== null) {
                element.id = savedID;
            }
            return (foundElm) ? false : true;
        };
    window.onload = function () {
        var image = document.getElementById("demo");
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false
        console.log('null', (image === null) ? true : false); // false
        console.log('find-by-id', isNull(image)); // false
        image.parentNode.removeChild(image);
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false ~ should be true?
        console.log('null', (image === null) ? true : false); // false ~ should be true?
        console.log('find-by-id', isNull(image)); // true ~ correct but there must be a better way than this?
    };
    </script>
</head>
<body>
    <div id="demo"></div>
</body>
</html>

Pada dasarnya kode di atas menunjukkan elemen yang disimpan ke dalam variabel dan kemudian dihapus dari DOM. Meskipun elemen telah dihapus dari DOM, variabel tetap mempertahankan elemen seperti ketika pertama kali dinyatakan. Dengan kata lain, ini bukan referensi langsung ke elemen itu sendiri, melainkan replika. Akibatnya, memeriksa nilai variabel (elemen) untuk keberadaan akan memberikan hasil yang tidak terduga.

The isNullFungsi adalah upaya saya untuk memeriksa eksistensi unsur-unsur dari variabel, dan bekerja, tapi saya ingin tahu apakah ada cara yang lebih mudah untuk mencapai hasil yang sama.

PS: Saya juga tertarik pada mengapa variabel JavaScript berperilaku seperti ini jika ada yang tahu beberapa artikel bagus yang berhubungan dengan subjek.

Justin Bull
sumber
18
Sebenarnya itu adalah referensi langsung ke elemen itu sendiri, hanya saja tidak ada dalam dokumen lagi. Fungsionalitas itu diperlukan karena Anda benar-benar dapat menarik elemen keluar dari DOM dan kemudian memasangnya kembali nanti dengan semua penangan acara / dll masih melekat padanya. Adapun mengapa variabel JS bertindak seperti itu? Karena akan sangat menyebalkan jika mereka tidak melakukannya. JS hanya menghapus variabel ketika Anda tidak lagi memiliki referensi APA SAJA untuk mereka. Bahasa tidak memiliki cara untuk mengetahui referensi mana yang Anda anggap penting dan yang menurut Anda tidak berharga.
Mark Kahn
@cwolves Menarik. Saya sudah mengalami ini berkali-kali sebelumnya dan tidak pernah benar-benar memikirkannya. Bahkan, dalam proyek saya saat ini, saya menyimpan elemen dalam array sebelum saya membuat perubahan padanya, kalau-kalau saya ingin mengembalikan perubahan.
Justin Bull
1
Pengumpulan sampah berjalan dari waktu ke waktu dan menghapus semua yang dianggapnya bisa. Tampaknya cukup buruk di sebagian besar browser, tetapi menjadi lebih baik karena pengembang menyadari bahwa beberapa browser berjalan selama berhari-hari atau berminggu-minggu di antara restart, jadi pengumpulan sampah yang baik sangat penting untuk kinerja browser. Pengembang web dapat membantu dengan menghapus properti (dan karenanya referensi ke hal-hal dalam memori) yang tidak lagi diperlukan.
RobG
2
@JustinBull hati-hati dengan menyimpan salinan elemen untuk dikembalikan. Saat menyimpan elemen DOM dalam array, referensi ke elemen DOM disimpan, bukan salinan, jadi perubahan yang dilakukan pada elemen DOM akan tercermin saat mereferensikan elemen array. Ini adalah kasus dengan semua objek di javascript (variabel tipe 'objek').
Anthony DiSanti

Jawaban:

545

Tampaknya beberapa orang mendarat di sini, dan hanya ingin tahu apakah ada elemen (sedikit berbeda dengan pertanyaan awal).

Itu yang sederhana seperti menggunakan metode memilih browser, dan memeriksa untuk truthy nilai (umumnya).

Misalnya, jika elemen saya memiliki iddari "find-me", saya cukup menggunakan ...

var elementExists = document.getElementById("find-me");

Ini ditentukan untuk mengembalikan referensi ke elemen atau null. Jika Anda harus memiliki nilai Boolean, cukup lemparkan !!sebelum panggilan metode.

Selain itu, Anda dapat menggunakan beberapa dari banyak metode lain yang ada untuk menemukan elemen, seperti (semuanya hidup document):

  • querySelector()/querySelectorAll()
  • getElementsByClassName()
  • getElementsByName()

Beberapa metode ini mengembalikan NodeList, jadi pastikan untuk memeriksa nya lengthproperti, karena NodeListadalah obyek, dan karena itu truthy .


Untuk benar-benar menentukan apakah suatu elemen ada sebagai bagian dari DOM yang terlihat (seperti pertanyaan yang awalnya ditanyakan), Csuwldcat memberikan solusi yang lebih baik daripada menggulirkan sendiri (karena jawaban ini biasanya berisi). Artinya, untuk menggunakan yangcontains() metode pada elemen DOM.

Anda bisa menggunakannya seperti itu ...

document.body.contains(someReferenceToADomElement);
alex
sumber
1
Persis apa yang saya cari! Jadi jelas lol, kenapa saya tidak memikirkan itu. Juga, apakah Anda tahu ada artikel bagus yang menjelaskan mengapa variabel bertindak seperti ini?
Justin Bull
3
Bahkan lebih pendek:var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
bennedich
2
@ButtleButkus Baca pertanyaan yang sebenarnya. Solusi yang Anda gunakan tidak masuk akal karena getElementById() akan mengembalikan referensi ke elemen DOM atau null, oleh karena itu, menggunakan typeof(terutama pada RHS) salah (jika tidak didefinisikan, kondisi LHS akan melempar a ReferenceError).
alex
2
Apakah ada alasan untuk menggunakan ini atas apa yang diposting di bawah ini: document.body.contains()yang tampaknya memiliki dukungan browser yang sangat bagus?
naksir
1
@Jonz Menghapus bagian jawaban lama , jangan lupa untuk pergi dan memilih csuwldcat
alex
310

Gunakan getElementById()jika tersedia.

Juga, inilah cara mudah untuk melakukannya dengan jQuery:

if ($('#elementId').length > 0) {
  // Exists.
}

Dan jika Anda tidak dapat menggunakan perpustakaan pihak ketiga, cukup pertahankan JavaScript:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}
Kon
sumber
2
Untuk proyek yang sedang saya kerjakan, saya tidak dapat menggunakan perpustakaan. Good-ol 'fashion raw code saja. Saya mengetahui metode jQuery itu, tetapi tidak bekerja pada elemen yang tidak terbungkus dalam wadah jQuery. Misalnya, $('#elementId')[0].lengthtidak akan menghasilkan hasil yang sama.
Justin Bull
8
Apakah ada alasan bagus untuk pernyataan if yang rumit seperti pada contoh kode kedua? Kenapa tidak sederhana saja if (element) {}? Ketika elemen tidak terdefinisi atau nol maka ungkapan ini salah. Jika elemen adalah elemen DOM maka ungkapan itu benar.
kayahr
2
@ Kayahr Ini terlalu rumit. getElementById()dispesifikasikan untuk kembali nulljika tidak menemukan elemen, jadi memeriksa nilai yang dikembalikan jujur adalah semua yang diperlukan.
alex
5
Saya pikir itu hanya akal sehat.
Kon
8
getElementByIdseharusnya tidak pernah kembali undefined. Bagaimanapun, element != nullcek akan mengambil ini.
191

Menggunakan Node.contains DOM API , Anda dapat memeriksa keberadaan elemen apa pun di halaman (saat ini di DOM) dengan mudah:

document.body.contains(YOUR_ELEMENT_HERE);

CATATAN CROSS-BROWSER : documentobjek di Internet Explorer tidak memiliki contains()metode - untuk memastikan kompatibilitas lintas-browser, gunakan document.body.contains()saja.

csuwldcat
sumber
4
Ini sepertinya jawaban akhir untuk masalah ini ... dan dukungannya, jika MDN dapat dipercaya cukup baik.
naksir
2
Ini jawaban terbaik. Perhatikan bahwa pemeriksaan saja document.contains()sudah cukup.
alex
@csuwldcat Ini bekerja untuk saya, setidaknya di Chrome dengan document.contains(document.documentElement). documentmemang memiliki Nodepada rantai prototipe, sejauh yang saya tahu ( document-> HTMLDocument-> Document-> Node)
alex
4
Ini memang jawaban terbaik: - ini adalah standar web - sangat didukung (agak mengejutkan itu tidak muncul di Firefox sampai versi 9, saya menduga karena itu adalah fungsi non-standar yang ditemukan di IE yang tidak standar sampai nanti) - itu harus menjadi yang tercepat karena menggunakan satu panggilan ke API asli
Jon z
2
@LeeSaxon Sintaksisnya adalah document.body.contains([selector]), yaitudocument.body.contains(document.getElementById('div')
iglesiasedd
67

Saya hanya melakukan:

if(document.getElementById("myElementId")){
    alert("Element exists");
} else {
    alert("Element does not exist");
}

Ini bekerja untuk saya dan belum memiliki masalah dengan itu ...

Anomali
sumber
1
Ini tidak ada hubungannya dengan pertanyaan aslinya. OP ingin tahu apakah referensi ke elemen DOM adalah bagian dari DOM yang terlihat atau tidak.
alex
16
Tapi membantu saya. Saya sedang mencari ujian sederhana keberadaan elemen; ini berhasil. Terima kasih.
khaverim
1
Jawaban ini berfungsi dengan baik, tetapi hanya ketika elemen memiliki id. Solusi yang lebih baik yang menjawab pertanyaan. Bagaimana memeriksa apakah elemen ada di DOM yang terlihat? dengan elemen apa pun, bahkan elemen tanpa ids adalah melakukan document.body.contains(element).
Edward
@Edward Ini adalah sesuatu yang sangat berbeda untukcontains()
alex
Saya mengerti. Saya hanya menyarankan dalam komentar saya bahwa jawaban lain lebih baik dan lebih cocok untuk pertanyaan itu.
Edward
11

Anda bisa memeriksa untuk melihat apakah properti parentNode adalah nol.

Itu adalah,

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}
mikechambers
sumber
Saya tahu ini adalah pertanyaan lama tetapi jawaban ini adalah jenis solusi sederhana yang elegan untuk pertanyaan yang saya cari.
poby
11
@ poby: Ini mungkin tampak elegan tetapi tidak benar-benar melakukan apa yang diminta. Hanya memeriksa apakah elemen memiliki elemen induk. Ini tidak menyiratkan bahwa elemen ada di DOM yang terlihat karena mungkin elemen induk tidak terhubung dengannya.
kayahr
Seseorang harus melalui semua orang tua orang tua untuk mencari tahu apakah yang terakhir adalah dokumen. Masalah lainnya adalah masih bisa di luar jangkauan yang terlihat atau tertutup atau tidak terlihat karena banyak alasan lain.
Arek Bal
Suatu elemen juga bisa memiliki parentNode hanya karena telah ditambahkan ke fragmen dokumen.
11

Dari Jaringan Pengembang Mozilla :

Fungsi ini memeriksa untuk melihat apakah suatu elemen ada di tubuh halaman. Karena berisi () bersifat inklusif dan menentukan apakah isi tubuh itu sendiri bukan maksud isInPage, kasus ini secara eksplisit mengembalikan false.

function isInPage(node) {
  return (node === document.body) ? false : document.body.contains(node);
}

simpul adalah simpul yang ingin kita periksa di dalam <body>.

Ekramul Hoque
sumber
+1, apakah ini juga berfungsi untuk simpul teks (atau sembarang komentar)?
Nikos M.
@NikosM. Seharusnya bekerja di tag html apa pun tapi saya tidak mengujinya.
Ekramul Hoque
4
Bukankah falseseharusnya begitu true?
Marc-André Lafortune
Jika nodeIS itu document.body, tentu metode harus kembali true? Yaitu,return (node === document.body) || document.body.contains(node);
daiscog
7

Solusi termudah adalah memeriksa properti baseURI , yang ditetapkan hanya ketika elemen dimasukkan dalam DOM, dan kembali ke string kosong ketika dihapus.

var div = document.querySelector('div');

// "div" is in the DOM, so should print a string
console.log(div.baseURI);

// Remove "div" from the DOM
document.body.removeChild(div);

// Should print an empty string
console.log(div.baseURI);
<div></div>

Peter Mortensen
sumber
5
Saya bahkan tidak tahu ada properti baseURI pada node DOM. Apa yang saya suka tentang pendekatan ini adalah bahwa ia menggunakan properti dari elemen itu sendiri, yang mungkin berarti itu akan berfungsi bahkan jika elemen tersebut ada dalam dokumen yang berbeda (misalnya iframe). Apa yang saya tidak suka tentang itu adalah sepertinya tidak berfungsi di luar Webkit.
DoctorDestructo
Hati-hati karena ini akan melemparkan kesalahan berikut jika elemen tidak dalam dokumen: Cannot read property 'baseURI' of null. Contoh:console.log(document.querySelector('aside').baseURI)
Ian Davis
Metode ini tidak dapat digunakan karena selalu mencetak string yang sama seperti sekarang.
Kagami Sascha Rosylight
4

solusi jQuery:

if ($('#elementId').length) {
    // element exists, do something...
}

Ini bekerja untuk saya menggunakan jQuery dan tidak perlu $('#elementId')[0]digunakan.

Code Buster
sumber
Mengapa $('#elementId')[0]sesuatu harus dihindari?
alex
Sudah lama saya menjawab ini, Jadi, menggunakan $ ('# elementId') [0] Saya yakin Anda selalu menunjukkan bahwa nilainya akan berada pada indeks ke-0. Dengan cara ini Anda selalu memeriksa elemen pertama yang terjadi. Apa yang ada beberapa kotak centang dengan nama yang sama, jadi seperti tombol radio. Waktu itu. Panjang akan sangat membantu.
Code Buster
3

Solusi csuwldcat tampaknya menjadi yang terbaik di antara banyak grup, tetapi sedikit modifikasi diperlukan untuk membuatnya berfungsi dengan benar dengan elemen yang ada dalam dokumen yang berbeda dari yang dijalankan oleh kode JavaScript, seperti iframe:

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

Perhatikan penggunaan ownerDocumentproperti elemen , tidak seperti biasa document(yang mungkin atau mungkin tidak merujuk ke dokumen pemilik elemen).

torazaburo memposting metode yang lebih sederhana yang juga bekerja dengan elemen non-lokal, tetapi sayangnya, ia menggunakan baseURIproperti, yang tidak diimplementasikan secara seragam di seluruh browser saat ini (saya hanya bisa membuatnya bekerja di yang berbasis WebKit ). Saya tidak dapat menemukan elemen atau properti simpul lain yang dapat digunakan dengan cara yang sama, jadi saya pikir untuk saat ini solusi di atas sama baiknya dengan yang didapat.

DoctorDestructo
sumber
3

Alih-alih mengulangi orang tua, Anda bisa mendapatkan persegi panjang pembatas yang semuanya nol ketika elemen dilepaskan dari DOM:

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    return (rect.top || rect.left || rect.height || rect.width)?true:false;
}

Jika Anda ingin menangani selubung tepi elemen lebar dan tinggi nol di atas nol dan kiri nol, Anda dapat memeriksa ulang dengan mengulangi orang tua hingga document.body:

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    if (element.top || element.left || element.height || element.width)
        return true;
    while(element) {
        if (element == document.body)
            return true;
        element = element.parentNode;
    }
    return false;
}
Erez Pilosof
sumber
Ini menyebabkan tata-ulang: gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics
Steven Vachon
3

Cara sederhana untuk memeriksa apakah ada elemen dapat dilakukan melalui kode jQuery satu baris.

Berikut adalah kode di bawah ini:

if ($('#elementId').length > 0) {
    // Do stuff here if the element exists
} else {
    // Do stuff here if the element does not exist
}
Ravi Agrawal
sumber
2

Opsi lain adalah element.closest :

element.closest('body') === null
Brian M. Hunt
sumber
2

Kode ini berfungsi untuk saya, dan saya tidak memiliki masalah dengannya.


    if(document.getElementById("mySPAN")) {
        // If the element exists, execute this code
        alert("Element exists");
    }
    else {
        // If the element does not exist execute this code
        alert("Element does not exists");
    }
Mohammad Ayoub Khan
sumber
1

Anda juga dapat menggunakan jQuery.contains, yang memeriksa apakah suatu elemen adalah turunan dari elemen lain. Saya meneruskan documentsebagai elemen induk untuk mencari karena setiap elemen yang ada pada halaman DOM adalah turunan dari document.

jQuery.contains( document, YOUR_ELEMENT)
nitinkhuranas
sumber
1

Periksa apakah elemennya adalah anak dari <html>via Node::contains():

const div = document.createElement('div');
document.documentElement.contains(div); //-> false

document.body.appendChild(div);
document.documentElement.contains(div); //-> true

Saya sudah membahas hal ini dan lebih banyak lagi di is-dom-detached .

Steven Vachon
sumber
1

Solusi sederhana dengan jQuery:

$('body').find(yourElement)[0] != null
mateusmaso
sumber
2
... atau$(document).find(yourElement).length !== 0
Grinn
1
Ini memanfaatkan itu null == undefined. Nilai yang dikembalikan sebenarnya adalah undefined. Membandingkannya nullsedikit aneh.
alex
1
// This will work prefectly in all :D
function basedInDocument(el) {

    // This function is used for checking if this element in the real DOM
    while (el.parentElement != null) {
        if (el.parentElement == document.body) {
            return true;
        }
        el = el.parentElement; // For checking the parent of.
    } // If the loop breaks, it will return false, meaning
      // the element is not in the real DOM.

    return false;
}
qandil afa
sumber
Dalam semua apa? Semua kasus?
Peter Mortensen
1
  • Jika sebuah elemen ada di DOM, orang tuanya juga harus di
  • Dan kakek nenek terakhir harus menjadi document

Jadi untuk memeriksa bahwa kita hanya loop ke parentNodepohon elemen sampai kita mencapai kakek terakhir

Gunakan ini:

/**
 * @param {HTMLElement} element - The element to check
 * @param {boolean}     inBody  - Checks if the element is in the body
 * @return {boolean}
 */
var isInDOM = function(element, inBody) {
    var _ = element, last;

    while (_) {
        last = _;
        if (inBody && last === document.body) { break;}
        _ = _.parentNode;
    }

    return inBody ? last === document.body : last === document;
};
silassare
sumber
2
Ini mungkin jawaban terbaik karena tidak menyebabkan rendering ulang di DOM.
Steven Vachon
Penjelasan akan dilakukan secara berurutan (menanggapi dengan mengedit jawaban Anda , bukan di sini dalam komentar).
Peter Mortensen
0

Saya menyukai pendekatan ini:

var elem = document.getElementById('elementID');

if (elem)
    do this
else
    do that

Juga

var elem = ((document.getElementById('elemID')) ? true:false);

if (elem)
    do this
else
    do that
Hugh
sumber
1
Mengapa tidak hanya !!jika Anda menginginkan Boolean?
alex
Jadi, jika elemen tidak memiliki id, maka itu dianggap tidak ada dalam DOM? Saya akan mengatakan ini salah.
Steven Vachon
0

Gunakan querySelectorAlldengan forEach,

document.querySelectorAll('.my-element').forEach((element) => {
  element.classList.add('new-class');
});

sebagai lawan dari:

const myElement = document.querySelector('.my-element');
if (myElement) {
  element.classList.add('new-class');
}
Rafal Enden
sumber
0

Coba yang berikut ini. Ini adalah solusi paling andal:

window.getComputedStyle(x).display == ""

Sebagai contoh,

var x = document.createElement("html")
var y = document.createElement("body")
var z = document.createElement("div")
x.appendChild(y);
y.appendChild(z);

z.style.display = "block";

console.log(z.closest("html") == null); // 'false'
console.log(z.style.display); // 'block'
console.log(window.getComputedStyle(z).display == ""); // 'true'
dexiang
sumber
1
Ini kemungkinan menyebabkan penataan
Steven Vachon
0

Semua elemen yang ada memiliki set parentElement, kecuali elemen HTML!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};
Jonah
sumber
Apakah selalu "HTML" ? Mungkinkah itu "html" ?
Peter Mortensen
x.tagName atau x.nodeName selalu dalam huruf besar tanpa mater bagaimana Anda menuliskannya dalam kode Anda
Jonah
0

kondisi ini cewek semua kasus.

function del() {
//chick if dom has this element 
//if not true condition means null or undifind or false .

if (!document.querySelector("#ul_list ")===true){

// msg to user
    alert("click btn load ");

// if console chick for you and show null clear console.
    console.clear();

// the function will stop.
    return false;
}

// if its true function will log delet .
console.log("delet");

}

Omar bakhsh
sumber
0

Saya lebih suka menggunakan node.isConnectedproperti ( Kunjungi MDN ).

Catatan: Ini akan mengembalikan true jika elemen ditambahkan ke ShadowRoot juga, yang mungkin tidak semua orang inginkan.

Contoh:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true
Robbendebiene
sumber