Сегодня мы создадим веб-страницу, на которой можно открыть до восьми веб-страниц. Это будет полезно, чтобы попрактиковаться верстать фреймы, а ещё если у вас вдруг есть необходимость работать с несколькими сайтами сразу.
⚠️ Не все сайты можно встраивать во фреймы — это определяется политикой безопасности сайта, которую прописывают разработчики в настройках сайта и сервера.
Логика проекта
На нашей странице будет девять ячеек. В восьми можно открывать разные сайты, а в центре будет блок управления с девятью кнопками. Восемь из них будут добавлять контент в свои фреймы, в девятая будет очищать все фреймы. По нажатию на кнопку добавления будет появляться окно, в котором нужно ввести адрес сайта.
Что будем делать:
- Создадим веб-страницу с базовой HTML-разметкой.
- Добавим фреймы, в которые будем встраивать сайты.
- Добавим кнопки, чтобы управлять фреймами.
- Добавим стили, чтобы всё выглядело красиво.
- Напишем один JS-скрипт, который будет добавлять содержимое во фрейм.
- Напишем второй JS-скрипт, который будет очищать все фреймы.
Попутно мы потренируемся делать вёрстку с помощью сетки и узнаем о возможностях тега <iframe>.
Создаём веб-страницу
Создадим файл index.html и добавим стандартную разметку:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>8 сайтов на одной странице</title>
<!-- Сюда подключим стили -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="grid-container">
<!-- В этом контейнере будут фреймы →
</div>
<!-- Сюда подключим скрипт -->
</body>
</html>
Настраиваем стили
Теперь создадим файл style.css и установим стили для элементов <html>
и <body>
, чтобы наш -контейнер растягивался на всю высоту:
/* настраиваем страницу */
body,
html {
/* высота 100% */
height: 100%;
/* без отступов */
margin: 0;
}
Теперь сделаем разметку контейнера с фреймами:
.grid-container {
/* превращаем элемент в грид-контейнер */
display: grid;
/* разбиваем пространство страницы на 3 колонки равной ширины*/
grid-template-columns: 1fr 1fr 1fr;
/* высота колонок 100% */
height: 100%;
}
Поскольку мы ещё не добавили никакого контента, у нас получилась пустая страница. Исправим это на следующем шаге.
Добавляем фреймы
Для добавления сайтов используем тег <iframe>
. Он создаёт контейнер, который позволяет вставить любой HTML-документ из другого источника. У нас будет 8 фреймов, и каждому из них нужно будет добавить свой id
, чтобы мы могли обращаться к фрейму в скрипте.
Добавляем фреймы в контейнер:
<div class="grid-container">
<iframe src="about:blank" id="frame1"></iframe>
<iframe src="about:blank" id="frame2"></iframe>
<iframe src="about:blank" id="frame3"></iframe>
<iframe src="about:blank" id="frame4"></iframe>
<iframe src="about:blank" id="frame5"></iframe>
<iframe src="about:blank" id="frame6"></iframe>
<iframe src="about:blank" id="frame7"></iframe>
<iframe src="about:blank" id="frame8"></iframe>
</div>
Каждому фрейму мы прописали атрибут src="about:blank"
. Это значит, что изначально фрейм будет пустым, без какого-либо контента.
Сразу добавим фреймам стили, чтобы каждый из них занимал всё доступное пространство в родительском контейнере:
iframe {
/* ширина фрейма 100% */
width: 100%;
/* высота фрейма 100% */
height: 100%;
/* граница */
border: 0.5px solid black;
}
Обновим страницу и увидим, что теперь появилась сетка:
Добавляем контейнер с кнопками
Мы хотим добавить блок с кнопками в центр нашего контейнера. Если посмотреть раскладку в инспекторе, мы увидим, что центральное место занимает пятый фрейм:
Чтобы на его месте появились кнопки, мы добавим после четвёртого фрейма отдельный контейнер для кнопок, где так же разместим их в три ряда и три колонки. Создаём контейнер:
<div class="buttons">
И задаём ему стили:
.buttons {
/* превращаем элемент в грид-контейнер */
display: grid;
/* разбиваем пространство на 3 колонки */
grid-template-columns: 1fr 1fr 1fr;
/* отступы */
padding: 1em;
/* граница */
border: 0.5px solid black;
/* расстояние между элементами в сетке */
gap: 1em;
}
Раскладка вышла такой же, как и для контейнера с фреймами:
Добавляем кнопки
Сделаем восемь кнопок для добавления контента в каждый фрейм и одну кнопку для очистки всех фреймов — её мы разместим в центре. У каждой кнопки пропишем свойство onclick
— оно будет обновлять фрейм или очищать его.
Сами функции пропишем позже, а пока укажем в свойствах кнопок их названия:
updateFrame()
будет отвечать за добавление контента во фрейм и принимать на вход номер фрейма;- а
clearFrames()
— за очистку фреймов.
<div class="buttons">
<button onclick="updateFrame(1)">Сайт 1</button>
<button onclick="updateFrame(2)">Сайт 2</button>
<button onclick="updateFrame(3)">Сайт 3</button>
<button onclick="updateFrame(4)">Сайт 4</button>
<button onclick="clearFrames()">Очистить</button>
<button onclick="updateFrame(5)">Сайт 5</button>
<button onclick="updateFrame(6)">Сайт 6</button>
<button onclick="updateFrame(7)">Сайт 7</button>
<button onclick="updateFrame(8)">Сайт 8</button>
</div>
Также добавим кнопке очистки класс buttons__btn-clear
, чтобы выделить её среди остальных кнопок. Сейчас пока будет незаметно, что она выделяется, потому что ещё нет класса в CSS-коде.
<button onclick="clearFrames()" class="buttons__btn-clear">Очистить</button>
Добавляем оставшиеся стили
Осталось раскрасить кнопки:
button {
/* вид курсора при наведении */
cursor: pointer;
/* отступы по высоте и ширине */
padding: 10px 20px;
/* граница */
border: 0.5px solid black;
/* скруглённые углы кнопок */
border-radius: 30px;
/* цвет кнопок */
background-color: bisque;
}
/* стили кнопки очистки */
.buttons__btn-clear {
/* цвет кнопки */
background-color: yellow;
}
Результат:
Пишем скрипт обновления фреймов
После того, как вся вёрстка готова, осталось написать скрипты.
Функция updateFrame
будет делать такое:
- Запрашивать в диалоговом окне URL — адрес веб-страницы.
- Проверять, введён ли URL.
- Обновлять фрейм, если URL введён.
Итак, начнём.
function updateFrame(frameNumber) {
const url = prompt("Введите адрес сайта " + frameNumber);
Здесь мы создали переменную url
, которая будет хранить строку, введённую через диалоговое окно. Для получения этих данных используем функцию prompt()
.
if (url) {
document.getElementById('frame' + frameNumber).src = url;
}
}
С помощью оператора if
мы проверяем, было ли что-то введено в диалоговом окне. Если URL введён и кнопка отмены не нажата, то дальше мы обновляем фрейм. Для этого обращаемся к фрейму по его id
и устанавливаем ему новый атрибут src
с введённым URL. После этого в указанном фрейме загружается контент веб-страницы.
Пишем скрипт очистки фреймов
Теперь напишем функцию clearFrames
, которая будет находить все фреймы, перебирать их и устанавливать их свойство src
в пустую строку ("").
function clearFrames() {
const frames = document.querySelectorAll("iframe");
Теперь с помощью метода document.querySelectorAll
выберем все элементы по селектору iframe
. Все найденные фреймы сохраним в переменную frames
.
frames.forEach(frame => {
frame.src = "";
});
}
С помощью метода forEach
функция перебирает каждый элемент в коллекции frames
и устанавливает свойство src
каждого элемента равным пустой строке ("").
Подключаем скрипты
Добавляем наши скрипты перед закрывающим тегом body
в index.html.
<script>
function updateFrame(frameNumber) {
const url = prompt("Введите адрес сайта " + frameNumber);
if (url) {
document.getElementById('frame' + frameNumber).src = url;
}
}
function clearFrames() {
const frames = document.querySelectorAll("iframe");
frames.forEach(frame => {
frame.src = "";
});
}
</script>
У нас получилась страница с девятью фреймами, в восьми из которых открываются сайты, а в центральной находятся кнопки управления:
Что можно улучшить
- Добавить подписи фреймам.
- Сделать адаптивную вёрстку.
- Добавить валидацию, то есть проверку, введённого адреса.
- Добавить обработчик ошибок.
Напишите в комментариях, чтобы бы вы добавили в этот проект, а лучшие из идей мы возьмём в следующую статью.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>8 сайтов на одной странице</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="grid-container">
<iframe src="about:blank" id="frame1"></iframe>
<iframe src="about:blank" id="frame2"></iframe>
<iframe src="about:blank" id="frame3"></iframe>
<iframe src="about:blank" id="frame4"></iframe>
<div class="buttons">
<button onclick="updateFrame(1)">Сайт 1</button>
<button onclick="updateFrame(2)">Сайт 2</button>
<button onclick="updateFrame(3)">Сайт 3</button>
<button onclick="updateFrame(4)">Сайт 4</button>
<button onclick="clearFrames()" class="buttons__btn-clear">Очистить</button>
<button onclick="updateFrame(5)">Сайт 5</button>
<button onclick="updateFrame(6)">Сайт 6</button>
<button onclick="updateFrame(7)">Сайт 7</button>
<button onclick="updateFrame(8)">Сайт 8</button>
</div>
<iframe src="about:blank" id="frame5"></iframe>
<iframe src="about:blank" id="frame6"></iframe>
<iframe src="about:blank" id="frame7"></iframe>
<iframe src="about:blank" id="frame8"></iframe>
</div>
<script>
function updateFrame(frameNumber) {
const url = prompt("Введите адрес сайта " + frameNumber);
if (url) {
document.getElementById('frame' + frameNumber).src = url;
}
}
function clearFrames() {
const frames = document.querySelectorAll("iframe");
frames.forEach(frame => {
frame.src = "";
});
}
</script>
</body>
</html>
body,
html {
/* высота 100% */
height: 100%;
/* без отступов */
margin: 0;
}
.grid-container {
/* превращаем элемент в грид-контейнер */
display: grid;
/* разбиваем пространство страницы на 3 колонки равной ширины */
grid-template-columns: 1fr 1fr 1fr;
/* высота колонок 100% */
height: 100%;
}
iframe {
/* ширина фрейма */
width: 100%;
/* высота фрейма */
height: 100%;
border: 0.5px solid black;
}
.buttons {
/* превращаем элемент в грид-контейнер */
display: grid;
/* разбиваем пространство на 3 колонки */
grid-template-columns: 1fr 1fr 1fr;
/* отступы */
padding: 1em;
/* граница */
border: 0.5px solid black;
/* расстояние между элементами в сетке */
gap: 1em;
}
button {
/* вид курсора при наведении */
cursor: pointer;
/* отступы по высоте и ширине */
padding: 10px 20px;
/* граница */
border: 0.5px solid black;
/*скруглённые углы кнопок */
border-radius: 30px;
/* цвет кнопок */
background-color: bisque;
}
/* стили кнопки очистки */
.buttons__btn-clear {
/* цвет кнопки */
background-color: yellow;
}