Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 128 additions & 87 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,91 +1,132 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Google</title>
</head>

<body>
<div class="header">
<ul class="header-wrap">
<div class="header-content">
<div class="links">
<li>Почта</li>
<li>Картинки</li>
</div>
<div class="img-links">
<li class="apps">
<img class="apps-icon" src="https://cdn3.iconfinder.com/data/icons/google-material-design-icons/48/ic_apps_48px-512.png">
</li>
<li class="profile">
<img class="profile-icon" src="https://sun9-39.userapi.com/c855032/v855032091/1cd62/XOu4Ii8wzq8.jpg?ava=1">
</li>
</div>
</div>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Google Search Replica</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header class="site-header">
<nav class="site-nav" aria-label="Основное">
<ul class="nav-list nav-list--links">
<li><a href="#">Почта</a></li>
<li><a href="#">Картинки</a></li>
</ul>
</div>
<div class="central">
<div class="icon">
<div class="google-icon">
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
</div>
</div>
<div class="main-search">
<div class="main-search-border">
<div class="search-begin">
<img class="search-icon" src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Vector_search_icon.svg/1200px-Vector_search_icon.svg.png">
</div>
<div class="input">
<input id="main-input" />
</div>
<div class="icons">
<div class="keyboard-icon">
<img src="https://www.google.com/tia/tia.png">
</div>
<div class="mic-icon">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Google_mic.svg/1200px-Google_mic.svg.png">
</div>
</div>

</div>
</div>
<div class="control-panel">
<div class="main-search-button">
<button>Поиск в Google</button>
</div>
<div class="auto-search-button">
<button>Мне повезёт!</button>
</div>
</div>
<div class="ext-info">
<span class="extra">Сервисы Google доступны на разных языках:&ensp;<a href="#">English</a>&ensp;&ensp;<a href="#">Беларуская</a>&ensp; </span>
</div>
</div>
<div class="upper-footer">
<ul class="upper-footer-ul">
<div class="upper-footer-left">
<li>Беларусь</li>
</div>

<ul class="nav-list nav-list--actions">
<li>
<button class="icon-button" type="button" aria-label="Приложения Google">
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path
d="M5 5h4V1H5zm7 0h4V1h-4zm7 0h4V1h-4zM5 12h4V8H5zm7 0h4V8h-4zm7 0h4V8h-4zM5 19h4v-4H5zm7 0h4v-4h-4zm7 0h4v-4h-4z"
/>
</svg>
</button>
</li>
<li>
<button class="icon-button icon-button--profile" type="button" aria-label="Профиль">
<img
src="https://sun9-39.userapi.com/c855032/v855032091/1cd62/XOu4Ii8wzq8.jpg?ava=1"
alt="Аватар пользователя"
loading="lazy"
/>
</button>
</li>
</ul>
</div>
<div class="footer">
<ul class="foot-ul">
<div class="footer-left">
<li>Реклама</li>
<li>Для бизнеса</li>
<li>Всё о Google</li>
<li>Как работает Google Поиск</li>
</nav>
</header>
<main class="site-main">
<section class="hero" aria-labelledby="search-title">
<h1 id="search-title" class="visually-hidden">Поиск Google</h1>
<img
class="hero__logo"
src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
alt="Google"
width="272"
height="92"
/>
<form class="search-form" action="https://www.google.com/search" method="get" role="search">
<label class="visually-hidden" for="search-input">Введите поисковый запрос</label>
<div class="search-field">
<span class="search-field__icon" aria-hidden="true">
<svg viewBox="0 0 24 24" focusable="false">
<path
d="M15.5 14h-.79l-.28-.27a6.471 6.471 0 0 0 1.57-4.23A6.5 6.5 0 1 0 9.5 16a6.471 6.471 0 0 0 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.02 14 5 11.98 5 9.5S7.02 5 9.5 5 14 7.02 14 9.5 11.98 14 9.5 14z"
/>
</svg>
</span>
<input
id="search-input"
name="q"
type="search"
autocomplete="off"
placeholder="Введите запрос или URL"
required
/>
<div class="search-field__actions">
<button class="icon-button" type="button" aria-label="Виртуальная клавиатура">
<svg viewBox="0 0 24 24" focusable="false">
<path
d="M3 5h18a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zm0 2v10h18V7zm2 2h2v2H5zm3 0h2v2H8zm3 0h2v2h-2zm3 0h2v2h-2zm3 0h2v2h-2zM5 12h2v2H5zm3 0h2v2H8zm3 0h2v2h-2zm3 0h2v2h-2zm3 0h2v2h-2zM5 15h14v2H5z"
/>
</svg>
</button>
<button class="icon-button" type="button" aria-label="Голосовой поиск">
<svg viewBox="0 0 24 24" focusable="false">
<path
d="M12 14a3 3 0 0 0 3-3V5a3 3 0 1 0-6 0v6a3 3 0 0 0 3 3zm5-3a5 5 0 0 1-10 0H5a7 7 0 0 0 6 6.92V21h2v-3.08A7 7 0 0 0 19 11z"
/>
</svg>
</button>
</div>
<div class="footer-right">
<li>Конфиденциальность</li>
<li>Условия</li>
<li>Настройки</li>
</div>
</ul>
</div>
</body>

</html>
</div>
<div class="search-actions">
<button type="submit">Поиск в Google</button>
<button type="button" data-action="lucky">Мне повезёт!</button>
</div>
</form>
<p class="languages">
Сервисы Google доступны на разных языках:
<a href="#">English</a>
<a href="#">Беларуская</a>
</p>
</section>
<section class="recent-searches" aria-labelledby="recent-title">
<div class="recent-searches__header">
<h2 id="recent-title">Недавние запросы</h2>
<button class="clear-button" type="button" data-action="clear" aria-label="Очистить историю запросов">
Очистить
</button>
</div>
<div class="recent-searches__list" id="recent-searches" role="list"></div>
</section>
</main>
<footer class="site-footer">
<div class="site-footer__region">Беларусь</div>
<div class="site-footer__links">
<nav aria-label="Дополнительные ссылки">
<ul>
<li><a href="#">Реклама</a></li>
<li><a href="#">Для бизнеса</a></li>
<li><a href="#">Всё о Google</a></li>
<li><a href="#">Как работает Google Поиск</a></li>
</ul>
</nav>
<nav aria-label="Правовая информация">
<ul>
<li><a href="#">Конфиденциальность</a></li>
<li><a href="#">Условия</a></li>
<li><a href="#">Настройки</a></li>
</ul>
</nav>
</div>
</footer>
<script src="script.js" type="module"></script>
</body>
</html>
99 changes: 99 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const RECENT_SEARCHES_KEY = "recent-searches";
const MAX_RECENT = 6;

const searchForm = document.querySelector(".search-form");
const searchInput = document.querySelector("#search-input");
const luckyButton = document.querySelector('[data-action="lucky"]');
const clearButton = document.querySelector('[data-action="clear"]');
const recentContainer = document.querySelector("#recent-searches");

const loadRecentSearches = () => {
try {
const stored = localStorage.getItem(RECENT_SEARCHES_KEY);
return stored ? JSON.parse(stored) : [];
} catch (error) {
console.warn("Не удалось загрузить историю запросов", error);
return [];
}
};

const saveRecentSearches = (queries) => {
try {
localStorage.setItem(RECENT_SEARCHES_KEY, JSON.stringify(queries));
} catch (error) {
console.warn("Не удалось сохранить историю запросов", error);
}
};

const renderRecentSearches = (queries) => {
recentContainer.innerHTML = "";

if (!queries.length) {
const emptyState = document.createElement("p");
emptyState.textContent = "История запросов пока пуста.";
emptyState.className = "recent-searches__empty";
recentContainer.append(emptyState);
return;
}

queries.forEach((query) => {
const item = document.createElement("div");
item.className = "recent-searches__item";

const button = document.createElement("button");
button.type = "button";
button.className = "recent-searches__chip";
button.textContent = query;
button.addEventListener("click", () => {
searchInput.value = query;
searchInput.focus();
});

item.append(button);
recentContainer.append(item);
});
};

const updateRecentSearches = (query) => {
const trimmed = query.trim();
if (!trimmed) {
return;
}

const current = loadRecentSearches();
const deduped = [trimmed, ...current.filter((item) => item.toLowerCase() !== trimmed.toLowerCase())];
const limited = deduped.slice(0, MAX_RECENT);
saveRecentSearches(limited);
renderRecentSearches(limited);
};

searchForm?.addEventListener("submit", (event) => {
const query = searchInput.value;
if (!query.trim()) {
event.preventDefault();
searchInput.focus();
return;
}

updateRecentSearches(query);
});

luckyButton?.addEventListener("click", () => {
const query = searchInput.value.trim();
const target = query
? `https://www.google.com/search?btnI=I&q=${encodeURIComponent(query)}`
: "https://www.google.com/doodles";
window.open(target, "_blank", "noopener");
});

clearButton?.addEventListener("click", () => {
localStorage.removeItem(RECENT_SEARCHES_KEY);
renderRecentSearches([]);
searchInput.focus();
});

renderRecentSearches(loadRecentSearches());

searchInput?.addEventListener("focus", () => {
searchInput.select();
});
Loading