Як перевірити, чи є елемент jQuery у DOM?


147

Скажімо, я визначаю елемент

$foo = $('#foo');

а потім дзвоню

$foo.remove()

від якоїсь події. Моє запитання полягає в тому, як я можу перевірити, чи було видалено $ foo з DOM чи ні? Я виявив, що це $foo.is(':hidden')працює, але це, звичайно, також повернеться правдою, якби я просто зателефонував $foo.hide().

Відповіді:


238

Подобається це:

if (!jQuery.contains(document, $foo[0])) {
    //Element is detached
}

Це все одно спрацює, якщо одного з батьків елемента було видалено (у такому випадку у самого елемента все ще буде батько).


14
робити $foo.closest(document.documentElement)швидше (якщо когось цікавить jsperf.com/jquery-element-in-dom )
уррака

48
@PerroAzul: Я знайшов набагато більш швидку альтернативу: jsperf.com/jquery-element-in-dom/2
SLaks

3
Ефективність викликала безпосереднє занепокоєння цим методом, дякую за посилання на тести @SLaks. Так виглядає $.contains(document.documentElement, $foo.get(0))це найшвидший спосіб.
Крістоф

10
Є чистий DOM спосіб зробити це, який є синтаксично більш читабельним, і я думаю, що дуже схожий з точки зору продуктивності:document.contains($foo[0])
Joel Cross

3
Вся ця розмова про виконання ...? Тести показують, що один метод займає 15 мікросекунд, а інший - 0,15 мікросекунд. Але дійсно, кого це хвилює - ти не збираєшся помічати різницю, якщо не зробиш це сто тисяч разів. І все може змінитися, якщо jQuery або JavaScript не буде оптимізовано. Використовуйте будь-який метод, який читається краще для вас і для того, хто повинен підтримувати ваш код у майбутньому.
Джеймс


5

Я щойно зрозумів відповідь, коли набирав своє запитання: Подзвони

$foo.parent()

Якщо $f00був видалений з DOM, то $foo.parent().length === 0. В іншому випадку його довжина буде не менше 1.

[Редагувати: це не зовсім правильно, оскільки вилучений елемент може мати ще батьків; наприклад, якщо ви вилучите а <ul>, у кожного його дочірнього <li>батька все одно буде батько. Використовуйте натомість відповідь SLaks.


2
... якщо тільки видалений вузол не був єдиною дитиною
Альваро Гонсалес

@ Альваро - Чому це має значення?
користувач113716

@patrick: Я щось пропустив? Що ви можете запевнити, якщо $ foo.parent (). Довжина більше нуля?
Альваро Гонсалес

@ Альваро - ОП перевіряється, щоб переконатися, що його $fooбуло вилучено з DOM. Якщо його було успішно видалено, він більше не матиме батьківського елемента. Тому $foo.parent().length === 0означає, що видалення було успішним.
користувач113716

1
$ foo.closest ("тіло") буде виправленням цієї техніки
georgephillips

4

Оскільки я не можу відповісти як коментар (гадаю, занадто низька карма), ось повна відповідь. Найшвидший спосіб легко розкрутити чек jQuery на підтримку браузера і збити постійні фактори до мінімуму.

Як видно також тут - http://jsperf.com/jquery-element-in-dom/28 - код виглядатиме так:

var isElementInDOM = (function($) {
  var docElt = document.documentElement, find,
      contains = docElt.contains ?
        function(elt) { return docElt.contains(elt); } :

        docElt.compareDocumentPosition ?
          function(elt) {
            return docElt.compareDocumentPosition(elt) & 16;
          } :
          ((find = function(elt) {
              return elt && (elt == docElt || find(elt.parentNode));
           }), function(elt) { return find(elt); });

  return function(elt) {
    return !!(elt && ((elt = elt.parent) == docElt || contains(elt)));
  };
})(jQuery);

Це семантично еквівалентно jQuery.contains (document.documentElement, elt [0]).


3

Напевно, найбільш досконалий спосіб:

document.contains(node); // boolean

Це також працює з jQuery:

document.contains($element[0]); // var $element = $("#some-element")
document.contains(this[0]); // in contexts like $.each(), `this` is the jQ object

Джерело з MDN

Примітка:


Як хтось ще подивився на цю відповідь? Відмінна відповідь +1 (я висунув видання, дякую)
Guilherme Nascimento

1

Мені сподобався такий підхід. Немає jQuery і немає DOM пошуку. Спочатку знайдіть верхнього батька (предка). Потім подивіться, чи це документElement.

function ancestor(HTMLobj){
  while(HTMLobj.parentElement){HTMLobj=HTMLobj.parentElement}
  return HTMLobj;
}
function inTheDOM(obj){
  return ancestor(obj)===document.documentElement;
}

1

замість ітерації батьків ви можете просто отримати обмежувальну пряму, яка є всіма нулями, коли елемент від'єднаний від dom

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

якщо ви хочете обробити край краю елемента нульової ширини та висоти в нульовому верхньому та нульовому лівому напрямку, ви можете двічі перевірити ітерацією батьків до документа.


Хоча цей фрагмент коду може вирішити проблему, він не пояснює, чому або як він відповідає на питання. Додайте пояснення до свого коду , оскільки це дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду. Флаггери / рецензенти: Для відповідей, що стосуються лише коду, таких як ця, downvote, не видаляти!
Лука Кібел

Невже це також не розпізнає приховані елементи як "не в DOM"? наприклад, елемент, display: noneякий не має обмежувальної реакції, також
Філіпп,

0

Погодьтеся з коментарем Перро. Це також можна зробити так:

$foo.parents().last().is(document.documentElement);

0
jQuery.fn.isInDOM = function () {
   if (this.length == 1) {
      var element = this.get(0);
      var rect = element.getBoundingClientRect();
      if (rect.top + rect.bottom + rect.width + rect.height + rect.left + rect.right == 0)
         return false;
      return true;
   }
   return false;
};

-1

Чому б не просто if( $('#foo').length === 0)...:?


@stevematdavies Питання полягає в тому, як "перевірити, чи є елемент у заданому об'єкті jQuery у DOM", а не "як перевірити, чи є елемент, що відповідає заданому рядку селектора, у DOM".
Тревор Бернхем

@TrevorBurnham: якщо чесно, повторний запит за допомогою селектора, який було створено $foo, і перевірка відповідності повторного запиту будь-якому елементу, здається життєздатним рішенням проблеми у багатьох сценаріях. Це може бути навіть швидше, ніж деякі інші рішення через те, як jQuery і браузери оптимізують певні селектори (наприклад, за ідентифікатором).
Метт

@Matt $ foo може бути елементом пам'яті, відірваним від DOM, і я міг би бути елементом із відповідним селектором у DOM. Люди, які шукають відповідь на це питання, ймовірно, хочуть перевірити, чи є він у DOM чи ні. Хтось, хто працює в таких речах, очевидно, знає, як запросити DOM.
TJ

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.