Какова базовая структура HTML-документа?

«Какова базовая структура HTML-документа?» — вопрос из категории Веб-тестирование, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Базовая структура валидного HTML5-документа состоит из обязательных деклараций и вложенных элементов. **Пример минимальной HTML-страницы:** ```html Заголовок страницы в браузере

Главный заголовок страницы (H1)

Это абзац текста, размеченный тегом <p>.

  • Элемент ненумерованного списка
  • Еще один элемент

© 2023

``` **Ключевые элементы и их назначение:** 1. `` — Декларация типа документа для HTML5. 2. `` — Корневой элемент документа. Атрибут `lang` задает язык. 3. `` — Секция с метаданными, не отображаемыми на странице. * `` — Кодировка символов. * `` — Настройки для адаптивного дизайна. * `` — Заголовок страницы (во вкладке браузера). * `<link>` — Подключение внешних ресурсов (CSS). 4. `<body>` — Секция, содержащая все отображаемое содержимое. * Семантические теги: `<header>`, `<main>`, `<footer>`, `<nav>`. * Теги контента: `<h1>`-`<h6>`, `<p>`, `<ul>/<ol>` с `<li>`, `<a>`. 5. `<script>` — Подключение JavaScript (обычно перед закрывающим `</body>`). </div> </div> </div> <div class="obscene-toggle-bar"> <button type="button" class="obscene-toggle-btn" id="obsceneToggleBtn" data-post-id="50851" data-nonce="01e92224db" data-ajax-url="https://hacksobesov.com/wp-admin/admin-ajax.php"> <span class="toggle-icon">🔞</span> <span class="toggle-label">Показать ответ 18+</span> <span class="toggle-warning">Нецензурная лексика</span> </button> </div> </div> <script> (function() { var btn = document.getElementById('obsceneToggleBtn'); var container = document.getElementById('answersContainer'); if (!btn || !container) return; var loaded = false; var loading = false; var label = btn.querySelector('.toggle-label'); var defaultLabel = 'Показать ответ 18+'; var openLabel = 'Скрыть ответ 18+'; function setLabel(text) { if (label) label.textContent = text; } function toggleVisibility() { var isOpen = container.classList.toggle('obscene-visible'); if (isOpen) { setLabel(openLabel); btn.classList.add('active'); } else { setLabel(defaultLabel); btn.classList.remove('active'); } } function loadObsceneAnswer() { loading = true; setLabel('Загрузка...'); var fd = new FormData(); fd.append('action', 'hsb_get_obscene_answer'); fd.append('post_id', btn.dataset.postId); fd.append('nonce', btn.dataset.nonce); fetch(btn.dataset.ajaxUrl, { method: 'POST', body: fd, credentials: 'same-origin' }) .then(function(r) { return r.json(); }) .then(function(res) { loading = false; if (res && res.success && res.data && res.data.html) { var block = document.createElement('div'); block.className = 'answer-column answer-obscene'; block.innerHTML = '<div class="question-main-answer question-obscene-answer markdown-content">' + '<h3>Ответ 18+ 🔞</h3>' + '<div class="main-answer-content obscene-answer-content">' + res.data.html + '</div>' + '</div>'; container.appendChild(block); loaded = true; setLabel(defaultLabel); toggleVisibility(); } else { setLabel('Ошибка загрузки'); setTimeout(function(){ setLabel(defaultLabel); }, 2000); } }) .catch(function() { loading = false; setLabel('Ошибка соединения'); setTimeout(function(){ setLabel(defaultLabel); }, 2000); }); } btn.addEventListener('click', function() { if (loading) return; if (loaded) { toggleVisibility(); return; } loadObsceneAnswer(); }); })(); </script> </div><!-- .entry-content --> </div><!-- .inside-article --> </article><!-- #post-## --> <!-- Навигация между вопросами --> <!-- Навигация между вопросами --> <!-- Навигация между вопросами --> <!-- Навигация между вопросами --> <!-- Навигация между вопросами --> <div class="question-navigation"> <div class="nav-links"> <div class="nav-previous"> <a href="https://hacksobesov.com/questions/qa-aqa-engineer/kak-organizovan-rabochij-den-qa-inzhenera-vo-vremya-sprinta/" rel="prev"> <span class="nav-subtitle"><i class="fas fa-arrow-left"></i> Предыдущий вопрос</span> <span class="nav-title"></span> </a> </div> <div class="nav-next"> <a href="https://hacksobesov.com/questions/qa-aqa-engineer/kakovy-kriterii-kachestvennoj-postanovki-zadachi-na-testirovanie/" rel="next"> <span class="nav-subtitle">Следующий вопрос <i class="fas fa-arrow-right"></i></span> <span class="nav-title"></span> </a> </div> </div> </div> </main><!-- #main --> </div><!-- #primary --> </div><!-- #page --> </div><!-- .site-container --> <div class="custom-footer-content"> <div class="custom-footer-copyright"> © ХакСобесов, 2026</div> <div class="custom-footer-social"> <a href="https://t.me/hacksobesov" target="_blank" class="social-icon tg-icon"> <i class="fab fa-telegram"></i> </a> <a href="https://www.youtube.com/@hacksobesovcom" target="_blank" class="social-icon yt-icon"> <i class="fab fa-youtube"></i> </a> </div> <a class="custom-footer-mail" href="mailto:support@hacksobesov.com"> <i class="fas fa-envelope"></i> support@hacksobesov.com </a> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/generatepress-child/*","/wp-content/themes/generatepress/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <div class="pp-modal-overlay" id="pp-modal" style="display:none;"> <div class="pp-modal"> <button type="button" class="pp-modal-close" id="pp-modal-close" title="">×</button> <div id="pp-step1"> <h3 class="pp-modal-title">Оформление подписки</h3> <p class="pp-step-label">Выберите способ оплаты:</p> <button type="button" class="pp-method-btn pp-method-site" id="pp-choose-ru"> <span class="pp-method-icon">💳</span> <span class="pp-method-text"><span class="pp-method-name">Российская карта</span><span class="pp-method-desc">Visa, MasterCard, МИР — через ЮKassa</span></span> </button> <button type="button" class="pp-method-btn pp-method-intl" id="pp-choose-intl"> <span class="pp-method-icon">🌎</span> <span class="pp-method-text"><span class="pp-method-name">Зарубежная карта</span><span class="pp-method-desc">Оплата через Sponsr — 15$</span></span> </button> </div> <div id="pp-step-intl" style="display:none;"> <button type="button" class="pp-back-btn" id="pp-back-intl" title="">← Назад</button> <h3 class="pp-modal-title">Международная оплата</h3> <div class="pp-intl-info"> <p class="pp-intl-price">1 месяц — <b>15$</b> (~1 250 ₽)</p> <p class="pp-intl-why">Стоимость подписки 999 ₽, но из-за комиссии сервиса сумма к оплате — 1 250 ₽</p> <div class="pp-intl-steps"> <p><b>Как оплатить:</b></p> <ol> <li>Перейдите на <a href="https://sponsr.ru/hacksobesov/" target="_blank" class="pp-intl-link">Sponsr</a></li> <li>Выберите уровень «Единоразовый платёж»</li> <li>Нажмите «ПОМОЧЬ ПРОЕКТУ»</li> <li>Войдите через соцсеть или email</li> <li>После оплаты отправьте чек (скриншот) и название категории на <a href="mailto:support@hacksobesov.com" class="pp-intl-link">support@hacksobesov.com</a> или в Telegram <a href="https://t.me/hs_supporter" target="_blank" class="pp-intl-link">@hs_supporter</a></li> </ol> <p class="pp-intl-note">Доступ будет активирован в течение 24 часов после подтверждения оплаты.</p> </div> <details class="pp-intl-cards"> <summary>💳 Какие карты принимаются?</summary> <div class="pp-intl-cards-body"> <p>✅ <b>Принимаются:</b></p> <ul> <li>Visa и Mastercard в любых валютах, выпущенных вне России</li> <li>Белорусские карты в BYN (не мультивалютные)</li> </ul> <p>❌ <b>НЕ принимаются:</b></p> <ul> <li>Карты из Эстонии, Латвии, Литвы, Швеции, Украины</li> <li>Карты Revolut и Wise</li> </ul> </div> </details> <a href="https://sponsr.ru/hacksobesov/" target="_blank" class="pp-form-submit" style="display:block;text-align:center;text-decoration:none;">Перейти на Sponsr</a> </div> </div> <div id="pp-step-email" style="display:none;"> <button type="button" class="pp-back-btn" id="pp-back-email" title="">← Назад</button> <h3 class="pp-modal-title">Вход на сайт</h3> <p class="pp-step-label">Для оформления подписки необходимо войти</p> <div class="pp-form-group"> <label class="pp-form-label" for="pp-auth-email">Email</label> <input type="email" class="pp-form-input" id="pp-auth-email" placeholder="your@email.com" required> </div> <div class="pp-form-error" id="pp-auth-email-error" style="display:none;"></div> <button type="button" class="pp-form-submit" id="pp-auth-send-code">Получить код</button> <p class="pp-email-hint">Нажимая «Получить код», вы соглашаетесь с <a href="/privacy-policy/" target="_blank" style="color:#36f9f6;text-decoration:none;">политикой конфиденциальности</a></p> </div> <div id="pp-step-code" style="display:none;"> <button type="button" class="pp-back-btn" id="pp-back-code" title="">← Назад</button> <h3 class="pp-modal-title">Введите код</h3> <p class="pp-step-label">Код отправлен на <span id="pp-code-email-display"></span></p> <div class="pp-code-inputs"> <input type="text" maxlength="1" class="pp-code-digit" data-index="0" inputmode="numeric" autocomplete="one-time-code"> <input type="text" maxlength="1" class="pp-code-digit" data-index="1" inputmode="numeric"> <input type="text" maxlength="1" class="pp-code-digit" data-index="2" inputmode="numeric"> <input type="text" maxlength="1" class="pp-code-digit" data-index="3" inputmode="numeric"> <input type="text" maxlength="1" class="pp-code-digit" data-index="4" inputmode="numeric"> <input type="text" maxlength="1" class="pp-code-digit" data-index="5" inputmode="numeric"> </div> <div class="pp-form-error" id="pp-auth-code-error" style="display:none;"></div> <button type="button" class="pp-form-submit" id="pp-auth-verify-code">Подтвердить</button> <button type="button" class="pp-resend-btn" id="pp-auth-resend" style="display:none;">Отправить код повторно</button> </div> <div id="pp-step2" style="display:none;"> <button type="button" class="pp-back-btn" id="pp-back" title="">← Назад</button> <h3 class="pp-modal-title">Оформление подписки</h3> <div class="pp-auth-status"> <span class="pp-auth-email-label">Аккаунт:</span> <span class="pp-auth-email-value" id="pp-logged-email"></span> </div> <div class="pp-tariffs"> <label class="pp-tariff" id="pp-tariff-1"> <input type="radio" name="pp-months" value="1" checked> <span class="pp-tariff-body"> <span class="pp-tariff-name">1 месяц</span> <span class="pp-tariff-price">999 ₽</span> </span> </label> <label class="pp-tariff pp-tariff--best" id="pp-tariff-3"> <input type="radio" name="pp-months" value="3"> <span class="pp-tariff-body"> <span class="pp-tariff-tag">-40%</span> <span class="pp-tariff-name">3 месяца</span> <span class="pp-tariff-price">1 799 ₽</span> <span class="pp-tariff-per">600 ₽/мес вместо 999 ₽</span> </span> </label> </div> <div class="pp-savings-info" style="display:none"> <div class="pp-savings-title">💰 При покупке на 3 месяца:</div> <div class="pp-savings-row">├ Экономия: <strong>1 198 ₽</strong> (40%)</div> <div class="pp-savings-row">├ Цена за месяц: <strong>600 ₽</strong> вместо 999 ₽</div> <div class="pp-savings-row">└ Итого: <strong>1 799 ₽</strong> вместо <s>2 997 ₽</s></div> </div> <form id="pp-payment-form"> <input type="hidden" name="months" id="pp-form-months" value="1"> <input type="hidden" id="pp_nonce" name="pp_nonce" value="21a2022d75" /><input type="hidden" name="_wp_http_referer" value="/questions/qa-aqa-engineer/kakova-bazovaya-struktura-html-dokumenta/" /> <div class="pp-form-group"> <label class="pp-form-label" for="pp-form-category">Категория видео</label> <select class="pp-form-select" id="pp-form-category" name="category" required> <option value="">Выберите категорию</option> <optgroup label="Программирование"> <option value="android-developer">Android Разработчик</option> <option value="c-sharp-developer">C# Разработчик</option> <option value="c-plus">C/C++ Разработчик</option> <option value="data-engineer">Data Инженер</option> <option value="devops-engineer">Devops Инженер</option> <option value="flutter-developer">Flutter Разработчик</option> <option value="frontend-developer">Frontend Разработчик</option> <option value="golang-developer">Golang Разработчик</option> <option value="ios-developer">IOS Разработчик</option> <option value="java-developer">Java Разработчик</option> <option value="nodejs-developer">Node.js Разработчик</option> <option value="php-developer">PHP Разработчик</option> <option value="python-developer">Python Разработчик</option> </optgroup> <optgroup label="Тестирование"> <option value="aqa-engineer">AQA / Automation</option> <option value="qa-aqa-engineer">QA Тестировщик</option> </optgroup> <optgroup label="Аналитика, Data Science и AI"> <option value="ai-engineer">AI Интегратор / AI инженер</option> <option value="ds-ml-engineer">Data Scientist / ML Инженер</option> <option value="data-analyst">Аналитик Данных</option> <option value="business-analyst">Бизнес Аналитик</option> <option value="product-analyst">Продуктовый Аналитик</option> <option value="system-analyst">Системный Аналитик</option> </optgroup> <optgroup label="Управление"> <option value="it-project-manager">Менеджер Проектов</option> <option value="it-product-manager">Продукт Менеджер</option> </optgroup> </select> </div> <div class="pp-form-error" id="pp-form-error" style="display:none;"></div> <button type="submit" class="pp-form-submit" id="pp-form-submit">Перейти к оплате</button> </form> </div> </div> </div> <style> .pp-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);backdrop-filter:blur(4px);z-index:9999;display:flex;align-items:center;justify-content:center;padding:20px} .pp-modal{background:#2a2740;border:1px solid rgba(255,126,219,0.2);border-radius:20px;padding:36px 32px;max-width:440px;width:100%;position:relative;box-shadow:0 20px 60px rgba(0,0,0,0.5);max-height:90vh;overflow-y:auto} .pp-modal-close{position:absolute;top:14px;right:18px;background:none;border:none;color:#6b7280;font-size:1.8rem;cursor:pointer;line-height:1;padding:0;outline:none!important;box-shadow:none!important}.pp-modal-close:hover,.pp-modal-close:focus,.pp-modal-close:active{color:#fff;outline:none!important;box-shadow:none!important;background:none!important} .pp-modal-title{font-size:1.4rem;font-weight:800;color:#fff;margin:0 0 28px;text-align:center} .pp-modal-sub{text-align:center;color:#ff7edb;font-size:1.1rem;font-weight:600;margin:0 0 24px} .pp-step-label{color:#8b95a5;font-size:0.9rem;margin-bottom:16px;text-align:center} .pp-method-btn{display:flex;align-items:center;gap:14px;width:100%;box-sizing:border-box;padding:18px 20px;border-radius:14px;border:1px solid rgba(255,255,255,0.1);background:rgba(255,255,255,0.03);cursor:pointer;transition:all 0.25s;text-decoration:none;margin-bottom:12px;color:inherit} .pp-method-btn:hover{border-color:rgba(255,126,219,0.4);background:rgba(255,255,255,0.06)} .pp-method-icon{font-size:1.4rem;flex-shrink:0;display:flex;align-items:center} .pp-method-text{display:flex;flex-direction:column;text-align:left} .pp-method-name{color:#fff;font-weight:700;font-size:1rem} .pp-method-desc{color:#6b7280;font-size:0.8rem;margin-top:2px} .pp-method-site:hover{border-color:#ff7edb} .pp-method-tg{color:inherit}.pp-method-tg:hover{border-color:#2AABEE;color:inherit} .pp-method-tg .pp-method-icon{color:#2AABEE}.pp-method-tg svg{flex-shrink:0} .pp-back-btn{background:none;border:none;color:#6b7280;font-size:0.9rem;cursor:pointer;padding:0;margin-bottom:12px;outline:none!important;box-shadow:none!important}.pp-back-btn:hover,.pp-back-btn:focus,.pp-back-btn:active{color:#fff;outline:none!important;box-shadow:none!important;background:none!important} .pp-form-group{margin-bottom:18px} .pp-form-label{display:block;color:#b8bfc9;font-size:0.85rem;margin-bottom:6px;font-weight:500} .pp-form-select,.pp-form-input{width:100%!important;padding:12px 16px!important;border-radius:10px!important;background:#323046!important;border:1px solid rgba(255,255,255,0.1)!important;color:#fff!important;font-size:0.95rem!important;outline:none!important;transition:border-color 0.2s;box-sizing:border-box!important;-webkit-appearance:none!important;appearance:none!important;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236b7280' d='M1 1l5 5 5-5'/%3E%3C/svg%3E")!important;background-repeat:no-repeat!important;background-position:right 16px center!important} .pp-form-input{background-image:none!important} .pp-form-select:focus,.pp-form-input:focus{border-color:#ff7edb!important} .pp-form-select option{background:#323046;color:#fff}.pp-form-select option[value=""]{color:#6b7280}.pp-form-select optgroup{background:#323046;color:#ff7edb;font-weight:700} .pp-form-error{background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);color:#ef4444;padding:10px 14px;border-radius:8px;font-size:0.85rem;margin-bottom:16px} .pp-form-submit{width:100%!important;cursor:pointer!important;font-size:1.05rem!important;margin-bottom:0!important;background:linear-gradient(135deg,#36f9f6 0%,#72F1B8 100%)!important;border:none!important;border-radius:12px!important;color:#0a0a1a!important;font-weight:700!important;padding:16px 36px!important;box-shadow:0 4px 20px rgba(54,249,246,0.25)!important;transition:all 0.25s!important} .pp-form-submit:hover{box-shadow:0 8px 30px rgba(54,249,246,0.35),0 0 20px rgba(114,241,184,0.15)!important} .pp-form-submit:disabled{opacity:0.6;cursor:not-allowed} .pp-tariffs{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:20px} .pp-tariff{cursor:pointer;position:relative} .pp-tariff input{display:none} .pp-tariff-body{display:flex;flex-direction:column;align-items:center;padding:16px 12px;border-radius:12px;border:1px solid rgba(255,255,255,0.1);background:rgba(255,255,255,0.03);transition:all 0.2s;text-align:center} .pp-tariff input:checked~.pp-tariff-body{border-color:#ff7edb;background:rgba(255,126,219,0.08);box-shadow:0 0 15px rgba(255,126,219,0.15)} .pp-tariff-name{color:#fff;font-weight:700;font-size:1rem} .pp-tariff-price{color:#fff;font-size:1.5rem;font-weight:800;margin-top:4px} .pp-tariff-per{color:#FEDE5D;font-size:0.75rem;margin-top:4px} .pp-tariff-tag{position:absolute;top:-8px;right:-4px;background:#FEDE5D;color:#1a1a2e;font-size:0.65rem;font-weight:800;padding:3px 8px;border-radius:6px} .pp-savings-info{background:rgba(254,222,93,0.08);border:1px solid rgba(254,222,93,0.25);border-radius:12px;padding:14px 18px;margin-bottom:20px;font-size:0.85rem;color:#d4d4d4;line-height:1.7} .pp-savings-title{color:#FEDE5D;font-weight:700;font-size:0.9rem;margin-bottom:4px} .pp-savings-row strong{color:#fff} .pp-savings-row s{color:#6b7280} .pp-email-hint{color:#6b7280;font-size:0.75rem;text-align:center;margin:12px 0 0;line-height:1.4} .pp-method-intl:hover{border-color:#FEDE5D} .pp-intl-price{text-align:center;font-size:1.2rem;color:#fff;margin-bottom:20px} .pp-intl-price b{color:#FEDE5D;font-size:1.4rem} .pp-intl-steps{background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.08);border-radius:12px;padding:16px 20px;margin-bottom:20px} .pp-intl-steps p{color:#b8bfc9;margin:0 0 8px} .pp-intl-steps ol{color:#d4d4d4;margin:0 0 12px;padding-left:20px;line-height:1.8} .pp-intl-link{color:#36f9f6;text-decoration:none}.pp-intl-link:hover{text-decoration:underline} .pp-intl-note{color:#FEDE5D;font-size:0.85rem;margin:0} .pp-intl-why{color:#8b95a5;font-size:0.85rem;text-align:center;margin:-10px 0 20px} .pp-intl-cards{margin-bottom:20px;margin-top:8px} .pp-intl-cards summary{color:#36f9f6;cursor:pointer;font-size:0.9rem;padding:8px 0;list-style:none} .pp-intl-cards summary::-webkit-details-marker{display:none} .pp-intl-cards summary::before{content:'▸ ';transition:transform 0.2s} .pp-intl-cards[open] summary::before{content:'▾ '} .pp-intl-cards-body{background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.08);border-radius:8px;padding:12px 16px;margin-top:8px;font-size:0.85rem;color:#d4d4d4} .pp-intl-cards-body p{margin:0 0 4px;font-size:0.85rem} .pp-intl-cards-body ul{margin:0 0 10px;padding-left:18px;line-height:1.6} .pp-intl-cards-body ul:last-child{margin-bottom:0} .pp-code-inputs{display:flex;gap:8px;justify-content:center;margin:20px 0} .pp-code-digit{width:48px!important;height:56px!important;text-align:center!important;font-size:1.5rem!important;font-weight:700!important;background:#323046!important;border:1px solid rgba(255,255,255,0.1)!important;border-radius:10px!important;color:#fff!important;outline:none!important;padding:0!important} .pp-code-digit:focus{border-color:#ff7edb!important} .pp-resend-btn{display:block;width:100%;background:none;border:none;color:#6b7280;font-size:0.85rem;cursor:pointer;padding:10px 0 0;text-align:center;outline:none!important;box-shadow:none!important} .pp-resend-btn:hover{color:#fff} .pp-auth-status{display:flex;align-items:center;gap:8px;padding:10px 14px;background:rgba(114,241,184,0.08);border:1px solid rgba(114,241,184,0.2);border-radius:10px;margin-bottom:20px;font-size:0.9rem} .pp-auth-email-label{color:#6b7280} .pp-auth-email-value{color:#72F1B8;font-weight:600} @media(max-width:480px){.pp-modal{padding:28px 20px}.pp-modal-title{font-size:1.2rem}.pp-tariffs{grid-template-columns:1fr 1fr}} </style> <script> (function(){ var modal=document.getElementById('pp-modal'); if(!modal)return; var step1=document.getElementById('pp-step1'); var stepIntl=document.getElementById('pp-step-intl'); var stepEmail=document.getElementById('pp-step-email'); var stepCode=document.getElementById('pp-step-code'); var step2=document.getElementById('pp-step2'); var formMonths=document.getElementById('pp-form-months'); var formCategory=document.getElementById('pp-form-category'); var formError=document.getElementById('pp-form-error'); var formSubmit=document.getElementById('pp-form-submit'); var paymentForm=document.getElementById('pp-payment-form'); var savingsInfo=document.querySelector('.pp-savings-info'); var ajaxUrl='https://hacksobesov.com/wp-admin/admin-ajax.php'; var nonce='21a2022d75'; var isLoggedIn=false; var authEmail=''; function hideAllSteps(){ step1.style.display='none';stepIntl.style.display='none'; stepEmail.style.display='none';stepCode.style.display='none';step2.style.display='none'; } function showStep(el){hideAllSteps();el.style.display='';} function showError(el,msg){el.textContent=msg;el.style.display='block';} function hideError(el){el.style.display='none';} function openModal(categorySlug){ showStep(step1); formError.style.display='none'; formSubmit.disabled=false;formSubmit.textContent='Перейти к оплате'; if(categorySlug)formCategory.value=categorySlug; modal.style.display='flex';document.body.style.overflow='hidden'; } var needsReload=false; function closeModal(){modal.style.display='none';document.body.style.overflow='';if(needsReload){window.location.reload();}} document.addEventListener('click',function(e){ var btn=e.target.closest('.premium-button'); if(!btn)return; e.preventDefault(); var href=btn.getAttribute('href')||''; var m=href.match(/category_([a-z0-9_-]+)/i); openModal(m?m[1]:''); }); document.getElementById('pp-modal-close').addEventListener('click',closeModal); modal.addEventListener('click',function(e){if(e.target===modal)closeModal();}); document.addEventListener('keydown',function(e){if(e.key==='Escape'&&modal.style.display==='flex')closeModal();}); document.getElementById('pp-choose-intl').addEventListener('click',function(){showStep(stepIntl);}); document.getElementById('pp-back-intl').addEventListener('click',function(){showStep(step1);}); document.getElementById('pp-choose-ru').addEventListener('click',function(){ if(isLoggedIn){showStep(step2);} else{showStep(stepEmail);} }); document.getElementById('pp-back-email').addEventListener('click',function(){showStep(step1);}); var authEmailInput=document.getElementById('pp-auth-email'); var authEmailError=document.getElementById('pp-auth-email-error'); var sendCodeBtn=document.getElementById('pp-auth-send-code'); sendCodeBtn.addEventListener('click',function(){ var email=authEmailInput.value.trim(); if(!email){showError(authEmailError,'Введите email');return;} hideError(authEmailError); sendCodeBtn.disabled=true;sendCodeBtn.textContent='Отправляем...'; var fd=new FormData(); fd.append('action','hsb_send_auth_code');fd.append('nonce',nonce);fd.append('email',email); fetch(ajaxUrl,{method:'POST',body:fd}) .then(function(r){return r.json();}) .then(function(res){ sendCodeBtn.disabled=false;sendCodeBtn.textContent='Получить код'; if(res.success){ authEmail=email; document.getElementById('pp-code-email-display').textContent=email; showStep(stepCode); document.querySelector('.pp-code-digit[data-index="0"]').focus(); var resendBtn=document.getElementById('pp-auth-resend'); resendBtn.style.display='none'; setTimeout(function(){resendBtn.style.display='block';},60000); } else { showError(authEmailError,res.data.message||'Ошибка отправки кода'); } }) .catch(function(){ sendCodeBtn.disabled=false;sendCodeBtn.textContent='Получить код'; showError(authEmailError,'Ошибка соединения'); }); }); var codeDigits=document.querySelectorAll('.pp-code-digit'); codeDigits.forEach(function(input,i){ input.addEventListener('input',function(){ this.value=this.value.replace(/\D/g,''); if(this.value&&i<5)codeDigits[i+1].focus(); }); input.addEventListener('keydown',function(e){ if(e.key==='Backspace'&&!this.value&&i>0){codeDigits[i-1].focus();} }); input.addEventListener('paste',function(e){ e.preventDefault(); var paste=(e.clipboardData||window.clipboardData).getData('text').replace(/\D/g,''); for(var j=0;j<6&&j<paste.length;j++){codeDigits[j].value=paste[j];} if(paste.length>=6)codeDigits[5].focus(); }); }); document.getElementById('pp-back-code').addEventListener('click',function(){ codeDigits.forEach(function(d){d.value='';}); showStep(stepEmail); }); var codeError=document.getElementById('pp-auth-code-error'); var verifyBtn=document.getElementById('pp-auth-verify-code'); verifyBtn.addEventListener('click',function(){ var code=''; codeDigits.forEach(function(d){code+=d.value;}); if(code.length!==6){showError(codeError,'Введите 6-значный код');return;} hideError(codeError); verifyBtn.disabled=true;verifyBtn.textContent='Проверяем...'; var fd=new FormData(); fd.append('action','hsb_verify_auth_code');fd.append('nonce',nonce); fd.append('email',authEmail);fd.append('code',code); fetch(ajaxUrl,{method:'POST',body:fd}) .then(function(r){return r.json();}) .then(function(res){ verifyBtn.disabled=false;verifyBtn.textContent='Подтвердить'; if(res.success){ isLoggedIn=true; needsReload=true; document.getElementById('pp-logged-email').textContent=res.data.email; // Запрашиваем свежий nonce уже залогиненным запросом — кука // только что установлена браузером, в этом fetch уже улетит. var fdN=new FormData();fdN.append('action','hsb_refresh_payment_nonce'); fetch(ajaxUrl,{method:'POST',body:fdN,credentials:'same-origin'}) .then(function(r){return r.json();}) .then(function(nr){ if(nr&&nr.success&&nr.data&&nr.data.nonce){ var pn=document.getElementById('pp_nonce'); if(pn)pn.value=nr.data.nonce; } }); showStep(step2); } else { showError(codeError,res.data.message||'Ошибка проверки кода'); if(res.data.expired){ codeDigits.forEach(function(d){d.value='';}); codeDigits[0].focus(); } } }) .catch(function(){ verifyBtn.disabled=false;verifyBtn.textContent='Подтвердить'; showError(codeError,'Ошибка соединения'); }); }); document.getElementById('pp-auth-resend').addEventListener('click',function(){ var fd=new FormData(); fd.append('action','hsb_send_auth_code');fd.append('nonce',nonce);fd.append('email',authEmail); fetch(ajaxUrl,{method:'POST',body:fd}); this.textContent='Код отправлен!'; var self=this; setTimeout(function(){self.textContent='Отправить код повторно';},3000); }); document.getElementById('pp-back').addEventListener('click',function(){showStep(step1);}); document.querySelectorAll('input[name="pp-months"]').forEach(function(r){ r.addEventListener('change',function(){ formMonths.value=this.value; if(savingsInfo)savingsInfo.style.display=this.value==='3'?'':'none'; }); }); paymentForm.addEventListener('submit',function(e){ e.preventDefault();formError.style.display='none'; var category=formCategory.value,months=formMonths.value; if(!category){showError(formError,'Выберите категорию видео');return;} formSubmit.disabled=true;formSubmit.textContent='Создаём платёж...'; var fd=new FormData(); fd.append('action','hsb_create_payment');fd.append('nonce',document.getElementById('pp_nonce').value); fd.append('category',category);fd.append('months',months); fetch(ajaxUrl,{method:'POST',body:fd}) .then(function(r){return r.json();}) .then(function(res){ if(res.success&&res.data.redirect_url){ localStorage.setItem('hsb_payment_id',res.data.payment_id); window.location.href=res.data.redirect_url; } else { showError(formError,(res.data&&res.data.message)||'Ошибка создания платежа'); formSubmit.disabled=false;formSubmit.textContent='Перейти к оплате'; } }) .catch(function(){ showError(formError,'Ошибка соединения. Попробуйте ещё раз.'); formSubmit.disabled=false;formSubmit.textContent='Перейти к оплате'; }); }); })(); </script> <script> document.addEventListener('DOMContentLoaded', function() { // Ждем загрузки DOM setTimeout(function() { const toggle = document.querySelector('.mobile-menu-toggle'); const nav = document.querySelector('.main-navigation') || document.querySelector('#site-navigation'); if (toggle && nav) { toggle.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); this.classList.toggle('active'); nav.classList.toggle('active'); // Добавим класс к body для overlay document.body.classList.toggle('mobile-menu-open'); }); // Закрытие при клике вне меню document.addEventListener('click', function(e) { if (!nav.contains(e.target) && !toggle.contains(e.target)) { toggle.classList.remove('active'); nav.classList.remove('active'); document.body.classList.remove('mobile-menu-open'); } }); } else { console.error('Menu elements not found!'); } }, 100); // Небольшая задержка для гарантии загрузки DOM }); </script> <script id="generate-a11y">!function(){"use strict";if("querySelector"in document&&"addEventListener"in window){var e=document.body;e.addEventListener("mousedown",function(){e.classList.add("using-mouse")}),e.addEventListener("keydown",function(){e.classList.remove("using-mouse")})}}();</script><script id="telegram-subscription-js-extra"> var telegram_subscription = {"ajax_url":"https://hacksobesov.com/wp-admin/admin-ajax.php","nonce":"48305e6c3b"}; var telegram_subscription = {"ajax_url":"https://hacksobesov.com/wp-admin/admin-ajax.php","nonce":"48305e6c3b","bot_username":"hacksobesov_premium_video_bot"}; //# sourceURL=telegram-subscription-js-extra </script> <script src="https://hacksobesov.com/wp-content/plugins/telegram-subscription-checker/js/telegram-subscription.js" id="telegram-subscription-js"></script> <script src="https://hacksobesov.com/wp-content/themes/generatepress-child/assets/js/category-filter.js" id="category-filter-js"></script> <script src="https://hacksobesov.com/wp-content/themes/generatepress-child/assets/js/code-sandbox-buttons.js" id="code-sandbox-buttons-js"></script> <script src="https://hacksobesov.com/wp-content/themes/generatepress-child/assets/js/common-filters.js" id="common-filters-js"></script> <script id="premium-tooltip-js-extra"> var premiumTooltipData = {"ajaxUrl":"https://hacksobesov.com/wp-admin/admin-ajax.php","nonce":"739161abab","categorySlug":""}; //# sourceURL=premium-tooltip-js-extra </script> <script src="https://hacksobesov.com/wp-content/themes/generatepress-child/assets/js/premium-tooltip.js" id="premium-tooltip-js"></script> <script src="https://hacksobesov.com/wp-content/themes/generatepress-child/assets/js/question-admin.js" id="question-admin-js"></script> <script src="https://vk.com/js/api/openapi.js?169" id="vk-openapi-js"></script> <script id="vk-openapi-js-after"> VK.init({ apiId: }); //# sourceURL=vk-openapi-js-after </script> <script id="codepen-button-js-extra"> var codeSandboxData = {"postType":"question","ajaxUrl":"https://hacksobesov.com/wp-admin/admin-ajax.php","nonce":"8305fd132b"}; //# sourceURL=codepen-button-js-extra </script> <script src="https://hacksobesov.com/wp-content/themes/generatepress-child/assets/js/code-sandbox-buttons.js" id="codepen-button-js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js" id="prismjs-core-js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js" id="prismjs-autoloader-js"></script> <script id="prismjs-autoloader-js-after"> document.addEventListener("DOMContentLoaded", function() { // Пропускаем блоки Code Block Pro (они уже подсвечены сервером) var codeBlocks = document.querySelectorAll("pre:not(.wp-block-code-block-pro-code-block) > code:not([class*=\"language-\"])"); codeBlocks.forEach(function(el) { el.classList.add("language-plaintext"); }); if (typeof Prism !== "undefined") { Prism.highlightAll(); } }); //# sourceURL=prismjs-autoloader-js-after </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/toolbar/prism-toolbar.min.js" id="prismjs-toolbar-js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js" id="prismjs-copy-js"></script> <script id="generate-menu-js-extra"> var generatepressMenu = {"toggleOpenedSubMenus":"1","openSubMenuLabel":"\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e","closeSubMenuLabel":"\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e"}; //# sourceURL=generate-menu-js-extra </script> <script src="https://hacksobesov.com/wp-content/themes/generatepress/assets/js/menu.min.js" id="generate-menu-js"></script> <script id="wp-emoji-settings" type="application/json"> {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://hacksobesov.com/wp-includes/js/wp-emoji-release.min.js"}} </script> <script type="module"> /*! This file is auto-generated */ const a=JSON.parse(document.getElementById("wp-emoji-settings").textContent),o=(window._wpemojiSettings=a,"wpEmojiSettingsSupports"),s=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const a=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===a[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,a){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!a(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,a){let r;const o=(r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),s=(o.textBaseline="top",o.font="600 32px Arial",{});return e.forEach(e=>{s[e]=t(o,e,n,a)}),s}function r(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}a.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),c.toString(),p.toString()].join(",")+"));",a=new Blob([e],{type:"text/javascript"});const r=new Worker(URL.createObjectURL(a),{name:"wpTestEmojiSupports"});return void(r.onmessage=e=>{i(n=e.data),r.terminate(),t(n)})}catch(e){}i(n=f(s,u,c,p))}t(n)}).then(e=>{for(const n in e)a.supports[n]=e[n],a.supports.everything=a.supports.everything&&a.supports[n],"flag"!==n&&(a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&a.supports[n]);var t;a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&!a.supports.flag,a.supports.everything||((t=a.source||{}).concatemoji?r(t.concatemoji):t.wpemoji&&t.twemoji&&(r(t.twemoji),r(t.wpemoji)))}); //# sourceURL=https://hacksobesov.com/wp-includes/js/wp-emoji-loader.min.js </script> <!-- Yandex.Metrika counter --> <script type="text/javascript"> (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(100805433, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true, ecommerce:"dataLayer" }); </script> <noscript><div><img src="https://mc.yandex.ru/watch/100805433" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter --> </div></div></div><div class="cookie-consent-banner" id="cookieConsentBanner" style="display: none;"> <div class="cookie-consent-banner-container"> <div class="cookie-consent-text"> Мы используем файлы cookie для улучшения работы сайта.<br> Продолжая использовать сайт, вы соглашаетесь с <a href="/privacy-policy" target="_blank">Политикой конфиденциальности</a>. </div> <div class="cookie-consent-buttons"> <button class="cookie-consent-btn accept" id="acceptCookies">Принимаю</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const cookieBanner = document.getElementById('cookieConsentBanner'); const acceptBtn = document.getElementById('acceptCookies'); // Проверяем, было ли уже принято решение о cookies if (!localStorage.getItem('cookieConsent')) { cookieBanner.style.display = 'flex'; } // Обработчик для кнопки "Принимаю" acceptBtn.addEventListener('click', function() { localStorage.setItem('cookieConsent', 'accepted'); cookieBanner.style.display = 'none'; }); }); </script> </body> </html> <!-- Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/ Served from: hacksobesov.com @ 2026-04-27 09:10:23 by W3 Total Cache -->