\n\n\n
Content
\n \n \n \n\n\n```\n\n## 10. Использование async/defer для скриптов\n\n```html\n\n\n\n\n\n\n\n\n```\n\n## 11. Проверка конкретного состояния\n\n```javascript\nconst isDOMReady = () => {\n return document.readyState === 'interactive' || \n document.readyState === 'complete';\n};\n\nconst isFullyLoaded = () => {\n return document.readyState === 'complete';\n};\n\nif (isDOMReady()) {\n console.log('Safe to query DOM');\n}\n\nif (isFullyLoaded()) {\n console.log('All resources loaded');\n}\n```\n\n## Лучшие практики\n\n1. **Для большинства случаев используй DOMContentLoaded**\n - Не ждёшь изображения и стили\n - Быстро выполняется\n\n2. **Используй load событие только если нужны все ресурсы**\n - Для работы с размерами элементов\n - Для загруженных изображений\n\n3. **Размещай скрипты в конце body с defer**\n ```html\n \n ```\n\n4. **Никогда не полагайся на readyState для синхронной проверки**\n - Используй события\n\n5. **Для динамического контента используй MutationObserver**\n - Спрашивай элемент каждый раз\n\n6. **Всегда проверяй элемент перед добавлением listener'а**\n ```javascript\n const button = document.querySelector('button');\n if (button) button.addEventListener('click', handler);\n ```","dateCreated":"2026-04-03T17:54:20.301342","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как проверить что DOM готов?

1.3 Junior🔥 203 комментариев
#JavaScript Core#Браузер и сетевые технологии

Комментарии (3)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Проверка готовности DOM

Проверка, что DOM полностью готов, критически важна для корректной работы JavaScript кода. Существует несколько способов убедиться, что все элементы страницы загружены и доступны.

1. document.readyState свойство

Проверяй состояние загрузки документа:

// Возможные значения: loading, interactive, complete

if (document.readyState === 'loading') {
  console.log('Документ ещё загружается');
} else if (document.readyState === 'interactive') {
  console.log('DOM готов, но ресурсы загружаются');
} else if (document.readyState === 'complete') {
  console.log('Всё готово: DOM и ресурсы');
}

// Используй switch для удобства
switch (document.readyState) {
  case 'loading':
    console.log('Loading...');
    break;
  case 'interactive':
    console.log('DOM ready!');
    break;
  case 'complete':
    console.log('Fully loaded!');
    break;
}

2. DOMContentLoaded событие

Лучший способ - слушай DOMContentLoaded событие:

// Выполнится когда DOM готов (не ждёт ассетов)
document.addEventListener('DOMContentLoaded', () => {
  console.log('DOM готов!');
  
  // Теперь безопасно работать с элементами
  const button = document.querySelector('button');
  button.addEventListener('click', () => {
    console.log('Clicked');
  });
});

// Альтернативный синтаксис (старый, не рекомендуется)
document.onDOMContentLoaded = () => {
  console.log('DOM готов!');
};

3. Load событие

Выполняется когда ВСЕ ресурсы загружены (изображения, стили, и т.д.):

// Выполнится после полной загрузки страницы
window.addEventListener('load', () => {
  console.log('Страница полностью загружена');
  
  // Все изображения загружены
  const images = document.querySelectorAll('img');
  console.log(`Загружено ${images.length} изображений`);
});

// Альтернативный синтаксис
window.onload = () => {
  console.log('Load complete');
};

4. Проверка readyState с обработкой

function onDOMReady(callback) {
  // Если уже готово
  if (document.readyState !== 'loading') {
    callback();
    return;
  }
  
  // Если ещё загружается
  document.addEventListener('DOMContentLoaded', callback);
}

onDOMReady(() => {
  console.log('DOM готов!');
  // Твой код здесь
});

5. Проверка конкретного элемента

function waitForElement(selector) {
  return new Promise((resolve) => {
    // Проверка каждые 100ms
    const checkInterval = setInterval(() => {
      const element = document.querySelector(selector);
      if (element) {
        clearInterval(checkInterval);
        resolve(element);
      }
    }, 100);
    
    // Таймаут - не жди бесконечно
    setTimeout(() => {
      clearInterval(checkInterval);
      resolve(null);
    }, 5000);
  });
}

// Использование
awaitForElement('.my-button').then(button => {
  if (button) {
    button.addEventListener('click', () => console.log('Clicked'));
  } else {
    console.log('Element not found');
  }
});

6. MutationObserver для отслеживания изменений

function waitForElements(selector) {
  return new Promise((resolve) => {
    // Проверь сразу
    const elements = document.querySelectorAll(selector);
    if (elements.length > 0) {
      resolve(elements);
      return;
    }
    
    // Следи за изменениями DOM
    const observer = new MutationObserver(() => {
      const elements = document.querySelectorAll(selector);
      if (elements.length > 0) {
        observer.disconnect();
        resolve(elements);
      }
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  });
}

awaitForElements('.list-item').then(items => {
  console.log(`Найдено ${items.length} элементов`);
  items.forEach(item => {
    console.log(item.textContent);
  });
});

7. IntersectionObserver для видимых элементов

function waitForVisibleElement(selector) {
  return new Promise((resolve) => {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          observer.disconnect();
          resolve(entry.target);
        }
      });
    });
    
    const element = document.querySelector(selector);
    if (element) {
      observer.observe(element);
    }
  });
}

awaitForVisibleElement('.hero').then(element => {
  console.log('Hero section is visible!');
});

8. Практический пример: инициализация приложения

class App {
  constructor() {
    this.initializeWhenReady();
  }
  
  initializeWhenReady() {
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', () => this.initialize());
    } else {
      this.initialize();
    }
  }
  
  initialize() {
    console.log('App initialized');
    this.setupEventListeners();
    this.loadData();
  }
  
  setupEventListeners() {
    const button = document.querySelector('button');
    if (button) {
      button.addEventListener('click', () => this.handleClick());
    }
  }
  
  loadData() {
    fetch('/api/data')
      .then(res => res.json())
      .then(data => console.log(data));
  }
  
  handleClick() {
    console.log('Button clicked');
  }
}

// Инициализируй приложение
const app = new App();

9. Script placement и порядок загрузки

<!DOCTYPE html>
<html>
<head>
  <title>Page</title>
  <!-- Скрипты здесь выполняются ДО DOMContentLoaded -->
  <script>
    console.log('Head script runs immediately');
    // document.querySelector('#main') будет null
  </script>
</head>
<body>
  <div id="main">Content</div>
  
  <!-- Скрипты перед закрытием body выполняются ПОСЛЕ dom -->
  <script>
    console.log('Body script - DOM готов');
    const main = document.querySelector('#main');
    console.log(main); // элемент найден!
  </script>
</body>
</html>

10. Использование async/defer для скриптов

<!-- defer - загружается асинхронно, выполняется после DOM -->
<script src="app.js" defer></script>

<!-- async - загружается асинхронно, выполняется сразу -->
<script src="analytics.js" async></script>

<!-- Блокирующий скрипт - ждёт выполнения -->
<script src="critical.js"></script>

11. Проверка конкретного состояния

const isDOMReady = () => {
  return document.readyState === 'interactive' || 
         document.readyState === 'complete';
};

const isFullyLoaded = () => {
  return document.readyState === 'complete';
};

if (isDOMReady()) {
  console.log('Safe to query DOM');
}

if (isFullyLoaded()) {
  console.log('All resources loaded');
}

Лучшие практики

  1. Для большинства случаев используй DOMContentLoaded

    • Не ждёшь изображения и стили
    • Быстро выполняется
  2. Используй load событие только если нужны все ресурсы

    • Для работы с размерами элементов
    • Для загруженных изображений
  3. Размещай скрипты в конце body с defer

    <script src="app.js" defer></script>
    
  4. Никогда не полагайся на readyState для синхронной проверки

    • Используй события
  5. Для динамического контента используй MutationObserver

    • Спрашивай элемент каждый раз
  6. Всегда проверяй элемент перед добавлением listener'а

    const button = document.querySelector('button');
    if (button) button.addEventListener('click', handler);