Làm cách nào để kiểm tra xem một phần tử có tồn tại trong DOM hiển thị không?


421

Làm thế nào để bạn kiểm tra một yếu tố cho sự tồn tại mà không sử dụng getElementByIdphương pháp?

Tôi đã thiết lập một bản demo trực tiếp để tham khảo. Tôi cũng sẽ in mã ở đây:

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

Về cơ bản đoạn mã trên biểu thị một phần tử đang được lưu trữ vào một biến và sau đó bị xóa khỏi DOM. Mặc dù phần tử đã bị xóa khỏi DOM, biến vẫn giữ nguyên phần tử như khi khai báo lần đầu tiên. Nói cách khác, nó không phải là một tham chiếu trực tiếp đến chính phần tử, mà là một bản sao. Kết quả là, kiểm tra giá trị của biến (phần tử) cho sự tồn tại sẽ cung cấp một kết quả không mong muốn.

Các isNullchức năng là nỗ lực của tôi để kiểm tra một yếu tố tồn tại từ một biến, và nó hoạt động, nhưng tôi muốn biết nếu có một cách dễ dàng hơn để đạt được kết quả tương tự.

Tái bút: Tôi cũng quan tâm đến việc tại sao các biến JavaScript hoạt động như thế này nếu có ai biết về một số bài viết hay liên quan đến chủ đề này.


18
Trên thực tế, nó là một tham chiếu trực tiếp đến chính yếu tố này, nó không còn trong tài liệu nữa. Chức năng đó là bắt buộc vì bạn thực sự có thể kéo một phần tử ra khỏi DOM và sau đó đưa nó trở lại sau với tất cả các trình xử lý sự kiện / vv vẫn được gắn vào nó. Đối với lý do tại sao các biến JS hành động như vậy? Bởi vì sẽ vô cùng khó chịu nếu họ không làm thế. JS chỉ xóa các biến khi bạn không còn BẤT K Reference tham chiếu nào đến chúng. Ngôn ngữ không có cách nào để biết tài liệu tham khảo nào bạn cho là quan trọng và bạn nghĩ nó không có giá trị.
Mark Kahn

@cwolves Thú vị. Tôi đã gặp điều này nhiều lần trước đây và chưa bao giờ thực sự nghĩ nhiều về nó. Thực tế, trong dự án hiện tại của tôi, tôi đang lưu các phần tử trong một mảng trước khi tôi thực hiện bất kỳ thay đổi nào đối với chúng, chỉ trong trường hợp tôi muốn hoàn nguyên các thay đổi.
Justin Bull

1
Bộ sưu tập rác chạy theo thời gian và xóa mọi thứ mà nó nghĩ là có thể. Có vẻ như khá tệ hại trong hầu hết các trình duyệt, nhưng đang trở nên tốt hơn khi các nhà phát triển nhận ra rằng một số trình duyệt chạy trong nhiều ngày hoặc vài tuần giữa các lần khởi động lại, vì vậy việc thu gom rác tốt là rất quan trọng đối với hiệu suất của trình duyệt. Các nhà phát triển web có thể giúp đỡ bằng cách xóa các thuộc tính (và do đó tham chiếu đến những thứ trong bộ nhớ) không còn cần thiết.
RobG

2
@JustinBull hãy cẩn thận với việc lưu trữ các bản sao của các phần tử để hoàn nguyên. Khi lưu trữ một phần tử DOM trong một mảng, một tham chiếu đến phần tử DOM được lưu trữ, không phải là một bản sao, vì vậy những thay đổi được thực hiện cho phần tử DOM sẽ được phản ánh khi tham chiếu phần tử của mảng. Đây là trường hợp với tất cả các đối tượng trong javascript (các biến loại 'đối tượng').
Anthony DiSanti

Câu trả lời:


545

Có vẻ như một số người đang hạ cánh ở đây, và chỉ muốn biết liệu một yếu tố có tồn tại không (một chút khác biệt với câu hỏi ban đầu).

Đó là đơn giản như sử dụng bất kỳ phương pháp lựa chọn của trình duyệt, và kiểm tra nó cho một truthy giá trị (nói chung).

Ví dụ, nếu yếu tố tôi đã có một idsố "find-me", tôi có thể chỉ cần sử dụng ...

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

Điều này được chỉ định để trả về một tham chiếu đến phần tử hoặc null. Nếu bạn phải có giá trị Boolean, chỉ cần quăng a !!trước khi gọi phương thức.

Ngoài ra, bạn có thể sử dụng một số trong nhiều phương thức khác tồn tại để tìm các phần tử, chẳng hạn như (tất cả đều sống document):

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

Một số phương thức này trả về a NodeList, vì vậy hãy chắc chắn kiểm tra thuộc tính của nó length, bởi vì a NodeListlà một đối tượng và do đó là sự thật .


Để thực sự xác định xem một phần tử có tồn tại như một phần của DOM hiển thị hay không (như câu hỏi ban đầu được hỏi), Csuwldcat cung cấp một giải pháp tốt hơn là tự lăn (như câu trả lời này được sử dụng để chứa). Đó là, sử dụng cáccontains() phương pháp trên các yếu tố DOM.

Bạn có thể sử dụng nó như vậy ...

document.body.contains(someReferenceToADomElement);

1
Chính xác những gì tôi đang tìm kiếm! Vì vậy, rõ ràng lol, tại sao tôi không nghĩ về điều đó. Ngoài ra, bạn có biết bất kỳ bài viết hay nào giải thích tại sao các biến hành động như thế này không?
Justin Bull

3
Thậm chí ngắn hơn:var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
bennedich

2
@BriptButkus Đọc câu hỏi thực tế. Giải pháp mà bạn đã sử dụng không có ý nghĩa vì getElementById() sẽ trả về tham chiếu đến phần tử DOM hoặc nulldo đó, sử dụng typeof(đặc biệt là trên RHS) là sai (nếu không được xác định, điều kiện LHS sẽ ném a ReferenceError).
alex

2
Có bất kỳ lý do để sử dụng điều này trên những gì được đăng dưới đây: document.body.contains()dường như có hỗ trợ trình duyệt rất tốt?
nghiền nát

1
@Jonz Đã xóa phần câu trả lời , đừng quên đi và bỏ phiếu cho csuwldcat
alex

310

Sử dụng getElementById()nếu nó có sẵn.

Ngoài ra, đây là một cách dễ dàng để làm điều đó với jQuery:

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

Và nếu bạn không thể sử dụng các thư viện của bên thứ ba, chỉ cần sử dụng JavaScript cơ bản:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}

2
Đối với dự án tôi đang thực hiện, tôi không thể sử dụng thư viện. Good-ol 'chỉ mã thô thời trang. Tôi biết phương thức jQuery đó, nhưng nó không hoạt động trên các phần tử không được gói trong bộ chứa jQuery. Ví dụ, $('#elementId')[0].lengthsẽ không tạo ra kết quả tương tự.
Justin Bull

8
Có bất kỳ lý do chính đáng cho một câu lệnh if phức tạp như vậy trong ví dụ mã thứ hai không? Tại sao không đơn giản if (element) {}? Khi phần tử không được xác định hoặc null thì biểu thức này là sai. Nếu phần tử là một phần tử DOM thì biểu thức là đúng.
kayahr

2
@kayahr Nó quá phức tạp. getElementById()được spec'd để trở lại nullnếu nó không tìm thấy nguyên tố này, vì vậy kiểm tra cho một truthy giá trị trả về là tất cả những gì cần thiết.
alex

5
Tôi nghĩ đó chỉ là lẽ thường.
Kon

8
getElementByIdkhông bao giờ phải trả lại undefined. Trong mọi trường hợp, element != nullkiểm tra sẽ chọn này.

191

Sử dụng API Node.contains DOM , bạn có thể kiểm tra sự hiện diện của bất kỳ yếu tố nào trong trang (hiện có trong DOM) khá dễ dàng:

document.body.contains(YOUR_ELEMENT_HERE);

LƯU Ý CROSS-BROWSER : documentđối tượng trong Internet Explorer không có contains()phương thức - để đảm bảo khả năng tương thích trình duyệt chéo, document.body.contains()thay vào đó hãy sử dụng .


4
Đây có vẻ như là câu trả lời cuối cùng cho vấn đề này ... và sự hỗ trợ của nó, nếu MDN được tin là khá tốt.
nghiền nát

2
Đây là câu trả lời tốt nhất. Lưu ý rằng chỉ cần kiểm tra document.contains()là đủ.
alex

@csuwldcat Nó hoạt động với tôi, ít nhất là trong Chrome với document.contains(document.documentElement). documentkhông có Nodetrên chuỗi nguyên mẫu của nó, theo như tôi có thể nói ( document-> HTMLDocument-> Document-> Node)
alex

4
Đây thực sự là câu trả lời hay nhất: - đó là một tiêu chuẩn web - nó được hỗ trợ rất tốt (hơi ngạc nhiên là nó không xuất hiện trong Firefox cho đến phiên bản 9, tôi đoán vì đó là một chức năng không chuẩn được phát minh trong IE mà không phải là được chuẩn hóa cho đến sau này) - nó phải nhanh nhất vì nó sử dụng một lệnh gọi đến API gốc
Jon z

2
@LeeSaxon Cú pháp là document.body.contains([selector]), tức làdocument.body.contains(document.getElementById('div')
iglesiasedd

67

Tôi chỉ đơn giản là làm:

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

Nó hoạt động với tôi và không có vấn đề gì với nó cả ...


1
Điều này không có gì để làm với câu hỏi ban đầu mặc dù. OP muốn biết liệu tham chiếu đến phần tử DOM có phải là một phần của DOM hiển thị hay không.
alex

16
Đã giúp tôi mặc dù. Tôi đang tìm kiếm thử nghiệm đơn giản về sự tồn tại của yếu tố; cái này hiệu quả Cảm ơn.
khaverim

1
Câu trả lời này hoạt động tốt, nhưng chỉ khi phần tử có một id. Giải pháp tốt hơn để trả lời câu hỏi Làm thế nào để kiểm tra xem phần tử có tồn tại trong DOM hiển thị không? với bất kỳ phần tử nào, ngay cả các phần tử không có ids là phải làm document.body.contains(element).
Edward

@Edward Đây là một cái gì đó hoàn toàn khác vớicontains()
alex

Tôi hiểu rồi Tôi chỉ gợi ý trong nhận xét của mình rằng các câu trả lời khác tốt hơn và phù hợp hơn với câu hỏi.
Edward

11

Bạn chỉ có thể kiểm tra xem thuộc tính ParentNode có null không.

Đó là,

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}

Tôi biết đây là một câu hỏi cũ nhưng câu trả lời này chính xác là loại giải pháp đơn giản thanh lịch cho câu hỏi mà tôi đang tìm kiếm.
poby

11
@poby: Nó có vẻ thanh lịch nhưng nó không thực sự làm những gì được yêu cầu. Nó chỉ kiểm tra nếu phần tử có phần tử cha. Điều này không ngụ ý rằng phần tử nằm trong DOM hiển thị vì có thể phần tử cha không được kết nối với phần tử đó.
kayahr

Một người sẽ phải thông qua tất cả các bậc cha mẹ của cha mẹ để tìm hiểu xem cuối cùng là tài liệu. Vấn đề khác là nó vẫn có thể nằm ngoài phạm vi có thể nhìn thấy hoặc bị che hoặc không thể nhìn thấy vì nhiều lý do khác.
Arek Bal

Một phần tử cũng có thể có một ParentNode chỉ nhờ vào việc được thêm vào một đoạn tài liệu.

11

Từ Mạng lưới nhà phát triển Mozilla :

Hàm này kiểm tra xem một phần tử có trong phần thân của trang không. Vì có chứa () là bao gồm và xác định xem phần thân có chứa chính nó không phải là ý định của isInPage hay không, trường hợp này trả về sai.

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

nút là nút chúng ta muốn kiểm tra trong <body>.


+1, điều này có làm việc cho các nút văn bản (tùy ý) (hoặc các nút nhận xét) không?
Nikos M.

@NikosM. Nó sẽ hoạt động trong bất kỳ thẻ html nào nhưng tôi đã không kiểm tra nó.
Ekramul Hoque

4
Nên không phải là falseđược true?
Marc-André Lafortune

Nếu nodeIS là document.body, chắc chắn phương pháp sẽ trở lại true? Tức là,return (node === document.body) || document.body.contains(node);
daiscog

7

Giải pháp đơn giản nhất là kiểm tra thuộc tính baseURI , chỉ được đặt khi phần tử được chèn vào DOM và nó trở lại thành một chuỗi trống khi nó bị xóa.

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>


5
Tôi thậm chí còn không biết có thuộc tính baseURI trên các nút DOM. Điều tôi thích về cách tiếp cận này là nó sử dụng một thuộc tính của chính phần tử, điều đó có nghĩa là nó sẽ hoạt động ngay cả khi phần tử nằm trong một tài liệu khác (ví dụ: iframe). Điều tôi không thích là nó dường như không hoạt động bên ngoài Webkit.
DoctorDeststallo

Cẩn thận vì điều này sẽ đưa ra lỗi sau nếu phần tử không có trong tài liệu : Cannot read property 'baseURI' of null. Ví dụ:console.log(document.querySelector('aside').baseURI)
Ian Davis

Phương pháp này không thể được sử dụng vì nó luôn in cùng một chuỗi như bây giờ.
Kagami Sascha Rosylight

4

Giải pháp jQuery:

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

Điều này làm việc cho tôi bằng cách sử dụng jQuery và không cần $('#elementId')[0]phải sử dụng.


Tại sao có $('#elementId')[0]điều gì đó cần tránh?
alex

Đã lâu tôi mới trả lời điều này, vì vậy, bằng cách sử dụng $ ('# ElementId') [0] Tôi tin rằng bạn luôn chỉ ra rằng giá trị sẽ ở chỉ số 0. Bằng cách này, bạn luôn luôn kiểm tra phần tử xuất hiện đầu tiên. Có gì có nhiều hộp kiểm có cùng tên, giống như một nút radio. Thời gian đó .length sẽ hữu ích.
Mã Buster

3

Giải pháp của csuwldcat dường như là tốt nhất trong nhóm, nhưng cần sửa đổi một chút để làm cho nó hoạt động chính xác với một phần tử trong tài liệu khác với mã JavaScript đang chạy, chẳng hạn như iframe:

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

Lưu ý việc sử dụng thuộc tính của phần tử ownerDocument, trái ngược với chỉ đơn giản là cũdocument (có thể hoặc không thể tham chiếu đến tài liệu chủ sở hữu của phần tử).

torazaburo đã đăng một phương thức thậm chí đơn giản hơn , cũng hoạt động với các yếu tố không phải cục bộ, nhưng thật không may, nó sử dụng thuộc baseURItính, không được triển khai thống nhất trên các trình duyệt tại thời điểm này (tôi chỉ có thể làm cho nó hoạt động trong các ứng dụng dựa trên WebKit ). Tôi không thể tìm thấy bất kỳ thuộc tính hoặc phần tử nút nào khác có thể được sử dụng theo cách tương tự, vì vậy tôi nghĩ rằng tại thời điểm này, giải pháp trên là tốt như nó có được.


3

Thay vì lặp lại cha mẹ, bạn chỉ có thể lấy hình chữ nhật giới hạn là tất cả các số không khi phần tử được tách ra khỏi DOM:

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

Nếu bạn muốn xử lý trường hợp cạnh của phần tử chiều rộng và chiều cao bằng 0 ở đỉnh 0 và 0 trái, bạn có thể kiểm tra lại bằng cách lặp lại cha mẹ cho đến khi 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;
}


3

Một cách đơn giản để kiểm tra xem một phần tử có tồn tại có thể được thực hiện thông qua mã một dòng của jQuery không.

Đây là đoạn mã dưới đây:

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


2

Mã này hoạt động với tôi và tôi không có vấn đề gì với nó.


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

1

Bạn cũng có thể sử dụng jQuery.contains, kiểm tra xem một phần tử có phải là hậu duệ của phần tử khác không. Tôi đã chuyển vào documentdưới dạng phần tử cha để tìm kiếm bởi vì bất kỳ phần tử nào tồn tại trên trang DOM đều là hậu duệ của document.

jQuery.contains( document, YOUR_ELEMENT)

1

Kiểm tra xem phần tử có phải là con của <html>thông qua không Node::contains():

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

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

Tôi đã bao gồm điều này và nhiều hơn nữa trong is-dom-tách ra .


1

Một giải pháp đơn giản với jQuery:

$('body').find(yourElement)[0] != null

2
... hoặc$(document).find(yourElement).length !== 0
Grinn

1
Điều này khai thác điều đó null == undefined. Giá trị thực trả lại sẽ là undefined. So sánh nó với nullmột chút kỳ lạ.
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;
}

Trong tất cả những gì? Mọi trường hợp?
Peter Mortensen

1
  • Nếu một phần tử nằm trong DOM , cha mẹ của nó cũng nên ở trong
  • Và ông bà cuối cùng nên là document

Vì vậy, để kiểm tra xem chúng ta chỉ cần lặp lại cho phần tử parentNode cho đến cây cho đến khi chúng ta đến được ông bà cuối cùng

Dùng cái này:

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

2
Đây có thể là câu trả lời tốt nhất vì nó không gây ra bất kỳ kết xuất lại nào trong DOM.
Steven Vachon

Một lời giải thích sẽ theo thứ tự (trả lời bằng cách chỉnh sửa câu trả lời của bạn , không phải ở đây trong các bình luận).
Peter Mortensen

0

Tôi thích cách tiếp cận này:

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

if (elem)
    do this
else
    do that

Cũng thế

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

if (elem)
    do this
else
    do that

1
Tại sao không chỉ là !!nếu bạn muốn một Boolean?
alex

Vì vậy, nếu phần tử không có id, thì nó được coi là không có trong DOM? Tôi nói điều này là sai.
Steven Vachon

0

Sử dụng querySelectorAll với forEach,

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

ngược lại với:

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

0

Hãy thử như sau. Đây là giải pháp đáng tin cậy nhất:

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

Ví dụ,

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'

1
Điều này có thể gây ra bố cục lại: gist.github.com/paulirish/5d52fb081b3570c81e3a#getcomputingstyle
Steven Vachon

0

Tất cả các phần tử hiện có có tập hợp ParentEuity, ngoại trừ phần tử HTML!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};

Có phải nó luôn luôn là "HTML" ? Nó có thể là "html" không?
Peter Mortensen

x.tagName hoặc x.nodeName luôn được viết hoa không có nghĩa là bạn viết nó như thế nào trong mã của bạn
Jonah

0

tình trạng này gà tất cả các trường hợp.

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

}


0

Tôi thích sử dụng node.isConnectedtài sản ( Truy cập MDN ).

Lưu ý: Điều này cũng sẽ trở lại đúng nếu phần tử cũng được gắn vào ShadowRoot, có thể không phải là hành vi mong muốn của mọi người.

Thí dụ:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.