Сверстать кнопочки как на картинке
- при клике на кнопку в первом ряду – выдавать в коносль надпись на кнопке
- при клике на кнопку во втором ряду – выдавать в коносль список классов
эти задания не обязательные, на потыкать javascript
Сверстать кнопочки как на картинке
Доделать задание, чтобы каждая кнопка имел стиль с цветом, а при клике на кнопку квадрат менял цвет на соответствующий кнопке, а также на нем появлялась та же надпись что и на кнопке
Допилить задание, чтобы как-то так выглядело, когда тыкаешь на строчки
img
с пустым атрибутом src
и из скрипта устанавливать атрибут картинки на значение row.dataset.image
Сверстать калькулятор, такой:
структура такая:
justify-content-center
,Реализовать чтобы:
=
вычислялся результатДоработать задание, добавить еще одно поле для ввода, в котором можно будет указать количество ячеек которое занимает колонка, (т.е. помимо формирование innerText) еще и формировать className вот так:
Наконец то мы впервые потыкаем скрипты.
Наверное, чтобы было удобнее работать с бутстрапом поставим себе плагин bootstrap. Для этого пойдем в extensions
найдем там плагин и установим его:
теперь чтобы добавить базовый шаблон достаточно написать b4-$
(можно и не целиком) и нажать enter или tab:
получим такое
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
И так, начнем с кнопочек
Само описание кнопок представлено тут https://getbootstrap.com/docs/4.6/components/buttons/
Сделаем кнопочку:
<div class="container p-2">
<button type="button" class="btn btn-primary">Я кнопочка</button>
</div>
ее можно тыкать:
Чтобы кнопочка что-то начала делать ей можно добавить команду. Для этого сначала надо добавить функцию, функцию надо пихать в блок script:
<div class="container p-2">
<button type="button" class="btn btn-primary">Я кнопочка</button>
</div>
<script>
// добавил функцию
function onMyKnopochkaPress () {
// выдаем сообщение
alert("Привет! =)")
}
</script>
теперь чтобы кнопочка начала работать, надо подключить ее к кнопке через атрибут onclick
<div class="container p-2">
<button type="button" class="btn btn-primary" onclick="onMyKnopochkaPress()">Я кнопочка</button>
</div>
<script>
function onMyKnopochkaPress () {
alert("Привет! =)")
}
</script>
проверяем:
то есть тут ничего сложного нет.
Альтернативный способ вывода – это писать в консольку, причем он более предпочтительный через alert:
<div class="container p-2">
<button type="button" class="btn btn-primary" onclick="onMyKnopochkaPress()">Я кнопочка</button>
</div>
<script>
// добавил функцию
function onMyKnopochkaPress () {
// пишу в консольку привет
console.log("Привет!")
}
</script>
консолька открывается через F12, в ней есть вкладка Console
, в которую будет писаться все что вызывается через console.log
На самом деле в onclick можно вообще любой код писать, и на самом деле функцию можно было не использовать и писать так
<div class="container p-2">
<button type="button" class="btn btn-primary" onclick="console.log("Привет!")">Я кнопочка</button>
</div>
<script>
function onMyKnopochkaPress () {
console.log("Привет!")
}
</script>
Но такой подход такой себе, так как его не удобно расширять
В javascript есть интересная переменная this
, который доступна в любой месте куда можно писать код. И в зависимости от того как была вызвана функция, она содержит разные значения.
Например, в нашем случае когда мы вызываем функцию тыкая на кнопочку, то в this будет информация о кнопке которую тыкнули:
<div class="container p-2">
<!-- заменил 'Привет!' на this -->
<button type="button" class="btn btn-primary" onclick="console.log(this)">Я кнопочка</button>
</div>
<script>
function onMyKnopochkaPress () {
console.log("Привет!")
}
</script>
теперь попробуем тыкнуть на кнопку:
то есть в консоль написалась прям разметка самой кнопке. Давай переделаем это так чтобы у нас использовалась функция:
<div class="container p-2">
<button type="button" class="btn btn-primary" onclick="onMyKnopochkaPress(this)">Я кнопочка</button>
</div>
<script>
// добавил аргумент, в кнопке выше в этот аргумент пихаю this
function onMyKnopochkaPress (button) {
console.log(button)
}
</script>
по идее работает так же
так кнопка это на самом деле объект, то у нее есть всякие свойства, например, свойство текста который в ней отображается. Мы можем получить доступ к нему через innerText
<div class="container p-2">
<button type="button" class="btn btn-primary" onclick="onMyKnopochkaPress(this)">Я кнопочка</button>
</div>
<script>
function onMyKnopochkaPress (button) {
// вывожу свойства текста (innerText) с кнопки
console.log(button.innerText)
}
</script>
Можно, например, выдать список классов, привязанных к кнопке:
<div class="container p-2">
<button type="button" class="btn btn-primary" onclick="onMyKnopochkaPress(this)">Я кнопочка</button>
</div>
<script>
function onMyKnopochkaPress (button) {
// вывожу список классов (classList) привязанных к кнопке
console.log(button.classList)
}
</script>
не особо интересно пока, но задание можно уже пилить =)
Идем дальше. Попробуем теперь изменять состояние какого-нибудь элемента при клике на разные кнопки.
Начинаем как обычно
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
теперь сверстаем три кнопки и один квадрат, как-то так:
<div class="container">
<div class="row justify-content-center mt-2">
<div class="col-auto">
<div class="btn btn-info">Красный</div>
<div class="btn btn-info">Оранжевый</div>
<div class="btn btn-info">Желтый</div>
</div>
</div>
<div class="row justify-content-center mt-2">
<div class="col-auto">
<div class="border shadow" style="width: 200px;height:200px;"></div>
</div>
</div>
</div>
во:
теперь я хочу, чтобы нажимая на каждую кнопку, цвет квадрата менялся на цвет написанный на кнопке.
Начну я с того же что я делал в прошлой задаче. Привяжу к кнопкам функцию, так как действие они все выполняют одно и то же то и функции хватит одной.
<div class="container">
<div class="row justify-content-center mt-2">
<div class="col-auto">
<div class="btn btn-info" onclick="onButtonClick(this)">Красный</div>
<div class="btn btn-info" onclick="onButtonClick(this)">Оранжевый</div>
<div class="btn btn-info" onclick="onButtonClick(this)">Желтый</div>
</div>
</div>
<div class="row justify-content-center mt-2">
<div class="col-auto">
<div class="border shadow" style="width: 200px;height:200px;"></div>
</div>
</div>
</div>
<script>
function onButtonClick (target) {
}
</script>
добавим вывод текста на кнопке в консоль (включаем ее через F12)
<script>
function onButtonClick (target) {
console.log(target.innerText)
}
</script>
проверяем:
теперь нам надо как-то повлиять на состояние квадрата. Для этого нам надо как-то получить доступ к нему. Для этих целей в html предусмотрена возможность указать элементу идентификатор. Делается это через атрибут id:
<div class="container">
<div class="row justify-content-center mt-2">
<div class="col-auto">
<!-- ... -->
</div>
</div>
<div class="row justify-content-center mt-2">
<div class="col-auto">
<!-- добавил id -->
<div id="kvadrat" class="border shadow" style="width: 200px;height:200px;"></div>
</div>
</div>
</div>
и теперь чтобы получить доступ к квадрату из кода мы пишем так:
<script>
function onButtonClick (target) {
// то есть объявил переменную node, запросил у документа элемент по id, в скобочках указал идентификатор
let k = document.getElementById("kvadrat");
console.log(k) // вывожу элемент в консоль
}
</script>
проверяем:
мы можем поменять содержимое квадрата на какой-нибудь текст:
<script>
function onButtonClick (target) {
let kvadrat = document.getElementById("kvadrat");
kvadrat.innerText = "Ооо, что происходит!"
}
</script>
можем поменять его текст на тот текст что был на кнопке на которую кликнули:
<script>
function onButtonClick (target) {
let kvadrat = document.getElementById("kvadrat");
kvadrat.innerText = target.innerText
}
</script>
если не нравится, что текст криво показывается не забываем, что квадрат — это просто блок, так что берем и добавляем стилей:
<div class="container">
<div class="row justify-content-center mt-2">
<div class="col-auto">
<!-- ... -->
</div>
</div>
<div class="row justify-content-center mt-2">
<div class="col-auto">
<!-- сделал квадрат флексом, добавил выравнивание по вертикали и по горизонтали по центру -->
<div id="kvadrat" class="border shadow d-flex align-items-center justify-content-center" style="width: 200px;height:200px;"></div>
</div>
</div>
</div>
осталось теперь придумать как менять цвет. Очевидно надо поменять у него стиль background-color, но как получить к нему доступ?
Для этого у любого элемента есть свойство style доступное из кода. Попробуем его вывести в консоль:
<script>
function onButtonClick (target) {
let kvadrat = document.getElementById("kvadrat");
console.log(kvadrat.style)
}
</script>
то есть тут получается целый набор значений каждое из которых можно менять. Вот есть, например, наша высота:
Свойствам, которые содержат тирешку типа background-color
соответствуют свойства, записанные в camelCase, например: backgroundColor
. То есть чтобы поменять цвет надо поменять значение backgroundColor. Заменим его на красный какой-нибудь:
<script>
function onButtonClick (target) {
let kvadrat = document.getElementById("kvadrat");
kvadrat.style.backgroundColor = "#ff003c";
}
</script>
проверяем:
как же сделать чтобы каждая кнопка менял цвет по-разному? А надо просто смотреть свойство innerText текущей кнопки, которая у нас попадает в параметр target и соответственно устанавливать разный цвет.
Тут нам пригодится обыкновенный if который такой же как в java или С#:
<script>
function onButtonClick (target) {
let kvadrat = document.getElementById("kvadrat");
if (target.innerText == "Красный") {
kvadrat.style.backgroundColor = "#ff003c";
} else if (target.innerText == "Оранжевый") {
kvadrat.style.backgroundColor = "#ff9500";
} else if (target.innerText == "Желтый") {
kvadrat.style.backgroundColor = "#ffd500";
}
}
</script>
кстати можно сделать плавное переключение цветов если добавить стиль transition
<div class="container">
<!-- ... -->
</div>
<script>
function onButtonClick (target) {
// ...
}
</script>
<style>
/* обрати внимание что прописывая путь по id, я использую решетку, вместо точки */
#kvadrat {
transition: all .3s;
}
</style>
так сразу красивее получается:
мы можем пробросить цвет кнопки в квадрат, но для этого надо чтобы у кнопки был обязательно прописан атрибут style, например, так:
<div class="container">
<div class="row justify-content-center mt-2">
<div class="col-auto">
<div class="btn btn-info" onclick="onButtonClick(this)" style="background-color: #ff003c;">Красный</div>
<div class="btn btn-info" onclick="onButtonClick(this)">Оранжевый</div>
<div class="btn btn-info" onclick="onButtonClick(this)">Желтый</div>
</div>
</div>
<div class="row justify-content-center mt-2">
<!-- ... -->
</div>
<script>
function onButtonClick (target) {
let kvadrat = document.getElementById("kvadrat");
if (target.innerText == "Красный") {
kvadrat.style.backgroundColor = target.style.backgroundColor; // тут просто пробрасываю стиль из кнопки
} else if (target.innerText == "Оранжевый") {
kvadrat.style.backgroundColor = "#ff9500";
} else if (target.innerText == "Желтый") {
kvadrat.style.backgroundColor = "#ffd500";
}
}
</script>
Сегодня попробуем запилить табличку. В ней буду выводить информацию по фильмам, а по нажатию на строку буду выдавать более подробную информацию в блок рядом с табличкой.
Начнем со стандартной вёрстки:
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container">
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
теперь определюсь с данными. У меня буду такой список:
Название | Год выпуска | Рейтинг кинопоиска | URL с обложкой, с кинопоиска | Режиссер |
---|---|---|---|---|
Унесённые призраками | 2001 | 8.4 | https://avatars.mds.yandex.net/get-kinopoisk-image/1629390/64becb5d-e7b9-4a56-8c71-5008294a854a/300x450 | Хаяо Миядзаки |
Малхолланд Драйв | 2002 | 7.6 | https://avatars.mds.yandex.net/get-kinopoisk-image/1777765/477bd555-16ee-47aa-be90-6a252c189414/300x450 | Дэвид Линч |
Мертвец | 1995 | 7.8 | https://avatars.mds.yandex.net/get-kinopoisk-image/1773646/707e78dc-43a0-4309-88f0-dee4ce7a4e57/300x450 | Джим Джармуш |
в табличку я буду выводить только название и рейтинг. Остальное буду выводить, когда буду тыкать на строки. Собственно, как ее добавить?
Для этого надо минимально прописать следующие теги:
<div class="container">
<table>
<thead>
<tr>
<th>Название</th>
<th>Рейтинг</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
на картинке красным я выделил область заголовка таблицы (это как правило первая строка), внутри этой области оранжевым выделено собственно само объявление строки (тег tr
), ну и синим выделены собственно теги ячеек th
, так как у меня в строке две ячейки то и тега две штуки.
если посмотреть, то будет выглядеть вот так:
выглядит уродливо, но это потому что мы не добавили классы bootstrap.
Добавим табличке класс table
<div class="container">
<table class="table">
<thead>
<tr>
<th>Название</th>
<th>Рейтинг</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
от теперь другое дело, таблица сразу респонсивная:
теперь добавим данных. Данные как ты, наверное, уже догадалась пишутся внутрь тега tbody.
На каждую строку данных надо добавлять сначала тег tr
, а потом внутри него прописывать теги td
для каждой ячейки. Тут небольшой тонкий момент, для ячеек заголовка используем тег th
, а для ячеек, данных используем td
, так принято, но на самом деле можно и там и сям использовать и тот и этот тег. Просто th
выделяет текст жирным.
Добавлю строчку:
<div class="container">
<table class="table">
<thead>
<!-- ... -->
</thead>
<tbody>
<tr>
<td>Унесённые призраками</td>
<td>8.4</td>
</tr>
</tbody>
</table>
</div>
и еще парочку:
<table class="table">
<thead>
<!-- ... -->
</thead>
<tbody>
<tr>
<!-- ... -->
</tr>
<tr>
<td>Малхолланд Драйв</td>
<td>7.6</td>
</tr>
<tr>
<td>Мертвец</td>
<td>7.8</td>
</tr>
</tbody>
</table>
посмотрим что нам предлагает для таблиц bootstrap: https://getbootstrap.com/docs/4.6/content/tables/ . Посмотри какие классы ты хочешь себе добавить. Главное обязательно добавь класс table-hover
чтобы при наведении на строку она выделялась, я добавлю себе еще темный заголовок:
<div class="container">
<table class="table table-hover">
<thead class="thead-dark"> <!-- темный заголовок сделал -->
<!-- ... -->
</thead>
<tbody>
<!-- ... -->
</tbody>
</table>
</div>
получится так
чтобы при наведении на строку курсор выглядел как указательный палец добавим класс со стилем, вот такой:
<style>
.table tr td:hover { /* :hover -- это псевдо класс, добавляется когда наводишь на элемент мышку */
cursor: pointer; /*курсор -- указатель*/
}
</style>
вообще наверное и td:hover хватило, но так точнее.
Теперь подумаем, что делать с остальными данными? Надо их как-то привязать к строкам, но так чтобы юзер их не видел. Для этого есть так называемые дата атрибуты, их можно добавлять к любому элементу, и они начинаются со слова data-
, а дальше любое свое слово.
Например, добавлю я год выпуска, делается это так:
<div class="container">
<table class="table table-hover">
<thead class="thead-dark">
<!-- ... -->
</thead>
<tbody>
<tr data-year="2001"> <!-- добавил data-year -->
<td>Унесённые призраками</td>
<td>8.4</td>
</tr>
<tr data-year="2002"> <!-- и тут-->
<td>Малхолланд Драйв</td>
<td>7.6</td>
</tr>
<tr data-year="1995"> <!-- и здесь -->
<td>Мертвец</td>
<td>7.8</td>
</tr>
</tbody>
</table>
</div>
так как их не видно, то сделаны они специально чтобы js их использовал, добавим функцию:
<script>
function onRowClick(row) {
console.log(row);
}
</script>
подключим ее к строкам:
<div class="container">
<table class="table table-hover">
<thead class="thead-dark">
<!-- ... -->
</thead>
<tbody>
<tr data-year="2001" onclick="onRowClick(this)">
<!-- ... -->
</tr>
<tr data-year="2002" onclick="onRowClick(this)">
<!-- ... -->
</tr>
<tr data-year="1995" onclick="onRowClick(this)">
<!-- ... -->
</tr>
</tbody>
</table>
</div>
проверим что все работает:
теперь собственно, как получить доступ к этим атрибутам? А очень просто, у всякого элемента при работе с ним в js есть свойство dataset
и вот в него эти атрибуты и попадают, подправим функцию:
<script>
function onRowClick(row) {
console.log(row.dataset);
}
</script>
проверяем:
то есть, чтобы вывести год привязанный к строке, надо написать так:
<script>
function onRowClick(row) {
console.log(row.dataset.year);
}
</script>
тыкаем:
добавим теперь оставшиеся наши данные в атрибуты, режиссера я буду пихать в data-director
, а картинку в data-image
, вот так:
<div class="container">
<table class="table table-hover">
<thead class="thead-dark">
<!-- ... -->
</thead>
<tbody>
<tr data-year="2001" data-director="Хаяо Миядзаки" data-image="https://avatars.mds.yandex.net/get-kinopoisk-image/1629390/64becb5d-e7b9-4a56-8c71-5008294a854a/300x450" onclick="onRowClick(this)">
<!-- ... -->
</tr>
<tr data-year="2002" data-director="Дэвид Линч" data-image="https://avatars.mds.yandex.net/get-kinopoisk-image/1777765/477bd555-16ee-47aa-be90-6a252c189414/300x450" onclick="onRowClick(this)">
<!-- ... -->
</tr>
<tr data-year="1995" data-director="Джим Джармуш" data-image=" https://avatars.mds.yandex.net/get-kinopoisk-image/1773646/707e78dc-43a0-4309-88f0-dee4ce7a4e57/300x450" onclick="onRowClick(this)">
<!-- ... -->
</tr>
</tbody>
</table>
</div>
вообще если так подумать есть смысл туда запихать и название, и рейтинг:
<!-- ... -->
<tr data-title="Унесённые призраками" data-rating="8.4" data-year="2001" data-director="Хаяо Миядзаки" data-image="..." onclick="onRowClick(this)">
<td>Унесённые призраками</td>
<td>8.4</td>
</tr>
<tr data-title="Малхолланд Драйв" data-rating="7.6" data-year="2002" data-director="Дэвид Линч" data-image="..." onclick="onRowClick(this)">
<td>Малхолланд Драйв</td>
<td>7.6</td>
</tr>
<tr data-title="Мертвец" data-rating="7.8" data-year="1995" data-director="Джим Джармуш" data-image="..." onclick="onRowClick(this)">
<td>Мертвец</td>
<td>7.8</td>
</tr>
<!-- ... -->
Теперь добавим блок справа куда я буду выводить подробную информацию. Для этого запихаем таблицу в строку,
<div class="container">
<div class="row">
<div class="col-8">
<table class="table table-hover">
<!-- ... -->
</table>
</div>
<div class="col-4">
<!-- ... -->
</div>
</div>
</div>
получится так, вот справа видно колонку если ее из инспектора выделить
то есть таблица занимает 8/12 а табличка 4/12. Добавим туда что-нибудь с рамочкой
<div class="container">
<div class="row">
<div class="col-8">
<table class="table table-hover">
<!-- ... -->
</table>
</div>
<div class="col-4">
<div class="shadow p-2 text-center">
Название
</div>
</div>
</div>
</div>
полчится так:
глянем как работают медиа классы, то есть которые меняют расположение элементов в зависимости от ширины экрана. Я хочу, чтобы, например, на большом экране от 768px в ширину у меня все было как сейчас, табличка 8/12, а название 4/12. Для этого я меняю класс col-8
на col-md-8
, а col-4
на col-md-4
,
<div class="container">
<div class="row">
<div class="col-md-8">
<table class="table table-hover">
<!-- ... -->
</table>
</div>
<div class="col-md-4">
<div class="shadow p-2 text-center">
Название
</div>
</div>
</div>
</div>
а теперь глянем как себя поведет верстка если мы начнем менять размеры экрана:
то есть для размеров которые меньше 768 он делает так чтобы элемент занимал всю ширину. Я не буду сильно на этом останавливаться, но если научится оперировать этими модификаторами (типа md
, там есть еще xl
, lg
, sm
), то можно делать сайт который будет удобно смотреть и на десктопе, и на телефоне.
В бутстрапе у многих классов есть их версия с md
, что позволяет очень гибко настраивать поведение. Например, у того же отступа можно для больших дисплеев использовать отступ p-md-2
, а для телефонов, например, уменьшать p-sm-1
, в общем, тьма возможностей =)
Сделаем теперь чтобы при клике на row у нас текст менялся на название фильма.
Обернем Название в тег span и добавим ему id:
<!-- ... -->
<div class="col-md-4">
<div class="shadow p-2 text-center">
<span id="title">Название</span>
</div>
</div>
а теперь как обычно подправим функцию так чтобы она меняла текст title на дата атрибут нашей строки, вот так:
<script>
function onRowClick(row) {
let title = document.getElementById("title")
title.innerText = row.dataset.title;
}
</script>
теперь сделаем еще так чтобы при клике на строку она фиксировалась как выделенная. Чтобы выделить строку при клике на нее я буду добавлять класс table-info
(больше классов тут https://getbootstrap.com/docs/4.6/content/tables/#contextual-classes)
<script>
function onRowClick(row) {
let title = document.getElementById("title")
title.innerText = row.dataset.title;
row.classList.add("table-info");
}
</script>
смотрим:
строки выделяются, но не сбрасываются цвета у предыдущих. Вот и вопрос как сделать сброс?
Можно завести переменную в которую будем фиксировать предыдущую строку, и при клике на очередную строку, у предыдущей будем удалять класс, вот так:
<script>
let previousRow = null; // завел переменную под строку
function onRowClick(row) {
let title = document.getElementById("title")
title.innerText = row.dataset.title;
if (previousRow) { // если предыдущая строка не пустая
previousRow.classList.remove("table-info") // то удаляем у нее класс
}
row.classList.add("table-info");
previousRow = row; // меняем предыдущую строку на текущую
}
</script>
проверка:
Более дубовый но более унивесальный, и чаще используется, просто удаляем класс у всех строк, и добавляем класс текущей
<script>
function onRowClick(row) {
let title = document.getElementById("title")
title.innerText = row.dataset.title;
// находим все теги tr, которые внутри tbody, который внутри тега с классом table
document.querySelectorAll(".table tbody tr").forEach(el => {
el.classList.remove("table-info"); // удаляем у них класс table-info
})
row.classList.add("table-info");
}
</script>
работает так же:
Ну база есть, теперь иди пили задачку =)
Вообще это такое разминочное задание. Несколько важных вещей которые помогут:
В html есть поля для ввода, чтобы их добавить достаточно написать:
<div class="container p-2">
<input>
</div>
получится что-то такое:
можно в него что-то написать:
выглядит не сильно впечатляюще, в bootstrap понятное дело целый раздел под такие поля есть https://getbootstrap.com/docs/4.6/components/forms/
мы пока не будем их сильно тыкать. Но главная идея такая, если ты хочешь, чтобы поле для ввода стало симпатичным ты добавляешь ему класс form-control
вот так
<div class="container p-2">
<input class="form-control">
</div>
получается такая красота:
поле для ввода пытается заполнить все пространство которое у него есть. Если попробовать добавить кнопочку, то она уже на одну строку не влезет:
<div class="container p-2">
<input class="form-control">
<button class="btn btn-primary">Кнопочка</button>
</div>
поэтому если хочется разметить кнопочку вслед за инпутом то надо обернуть во строку и запихать их в колонки:
<div class="container p-2">
<div class="row">
<div class="col">
<input class="form-control" />
</div>
<div class="col">
<button class="btn btn-primary">Кнопочка</button>
</div>
</div>
</div>
правда в этом случае поле для ввода займет всю колонку, а кнопочка ровно столько сколько ее надо:
поэтому если хочется, чтобы кнопка тоже занимала колонку целиком, то надо добавить кнопочке класс w-100
, этот класс добавит кнопке стиль width: 100%
и тогда кнопка тоже начнет занимать все пространство:
<div class="container p-2">
<div class="row">
<div class="col">
<input class="form-control" />
</div>
<div class="col">
<button class="btn btn-primary w-100">Кнопочка</button>
</div>
</div>
</div>
правда это не всегда желательно, чаще хочется, чтобы кнопка была ровно того размера сколько ей надо, тогда просто класс колонки и кнопки меняем на col-auto
<div class="container p-2">
<div class="row">
<div class="col">
<input class="form-control" />
</div>
<div class="col-auto">
<button class="btn btn-primary w-100">Кнопочка</button>
</div>
</div>
</div>
можно еще надпись для поля добавить справа, то же используя col-auto
<div class="container p-2">
<div class="row">
<div class="col-auto"> <!-- добавил -->
Поле для ввода
</div>
<div class="col">
<input class="form-control" />
</div>
<div class="col-auto">
<button class="btn btn-primary w-100">Кнопочка</button>
</div>
</div>
</div>
вот так выйдет:
в принципе надо понять, что col
ведет себя как flex-grow: 1
, то есть занимает все возможное пространство, col-auto
ведет себя как flex-grow: 0
то есть занимает только то что содержимому колонке надо, ну а col-*
с циферками занимает столько сколько указано.
Тут еще не отцентрировано по вертикали получается, добавим строке класс align-items-center
<div class="container p-2">
<div class="row align-items-center">
<div class="col-auto">
Поле для ввода
</div>
<div class="col">
<input class="form-control" />
</div>
<div class="col-auto">
<button class="btn btn-primary w-100">Кнопочка</button>
</div>
</div>
</div>
красота:
Теперь вернемся к полю для ввода и как с ним работать, добавим ему id
<div class="container p-2">
<div class="row align-items-center">
<!-- ... -->
<div class="col">
<input id="textField" class="form-control" />
</div>
<!-- ... -->
</div>
</div>
добавим функцию
<script>
function onButtonClick(btn) {
}
</script>
подцепим ее к кнопке:
<div class="container p-2">
<div class="row align-items-center">
<!-- ... -->
<div class="col-auto">
<button class="btn btn-primary w-100" onclick="onButtonClick(this)">Кнопочка</button>
</div>
</div>
</div>
и теперь попробуем написать чего-нибудь в поле для ввода:
<script>
function onButtonClick(btn) {
let textField = document.getElementById("textField"); // взял поле по id
textField.value = "Привет! =)"; // поменял текст в поле, у полей текст хранится в value
}
</script>
мы можем не только изменять значение, но и читать то что в этом поле написано:
<script>
function onButtonClick(btn) {
let textField = document.getElementById("textField"); // взял поле по id
alert(textField.value) // выведу alert c текстом который в поле
}
</script>
ну и можем изменять значение поля, использую текущее значение, например, добавлять смайлик к введённому тексту:
<script>
function onButtonClick(btn) {
let textField = document.getElementById("textField"); // взял поле по id
let newValue = textField.value + "=)";
textField.value = newValue;
}
</script>
И еще один момент который пригодится для решения задачки. В javascript если в строку написать код, то этот код можно будет запустить и получить результат. Выглядит дико, но работает:
<script>
function onButtonClick(btn) {
let textField = document.getElementById("textField"); // взял поле по id
let code = "5+10";
textField.value = eval(code);
}
</script>
зачем нам это нужно, а затем что мы можем, например, написать в поле для ввода любое арифметическое выражение и получить его результат:
<script>
function onButtonClick(btn) {
let textField = document.getElementById("textField"); // взял поле по id
let code = textField.value;
textField.value = eval(code);
}
</script>
ужас просто, в природе использовать запрещается, но в нашем случае удобно:
ну все айда пилить калькулятора =О
Тут мы до этого использовали уже готовую разметку и используя привязанные к элементам данные через data-атрибуты изменяли значения в других элементах.
А сегодня попробуем создавать прям новые элементы.
Начнем как всегда с базы
<!doctype html>
<html lang="en">
<head>
<title>Title</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container p-2">
</div>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
</body>
</html>
добавим тут какую-нибудь кнопочку и поле для ввода
<div class="container p-2">
<div class="row">
<div class="col">
<input type="text" class="form-control">
</div>
<div class="col-auto">
<button class="btn btn-info">Добавить</button>
</div>
</div>
</div>
добавим обработчик нажатия на кнопку:
<div class="container p-2">
<div class="row">
<div class="col">
<input type="text" class="form-control">
</div>
<div class="col-auto">
<!-- привязал реакцию на клик -->
<button class="btn btn-info" onclick="onButtonClick(this)">Добавить</button>
</div>
</div>
</div>
<script>
function onButtonClick(btn) {
console.log(btn)
}
</script>
теперь попробуем создать новый элемент. Чтобы его создать его надо куда-то помещать, то есть в разметке он должен где-то оказаться. Добавим, например, новую строку и присвоим ей id:
<div class="container p-2">
<div class="row">
<!-- ... -->
</div>
<div id="newRow" class="row"></div>
</div>
теперь напишем следующий код в реакцию на клик:
function onButtonClick(btn) {
let newRow = document.getElementById("newRow"); // взяли строку по идентификатору
let col = document.createElement("div") // создали в памяти пустой div (по сути пара тегов <div></div>)
col.innerText = "Я колонка" // вписали в него "Я колонка" (теперь у нас получится <div>Я колонка</div>)
newRow.appendChild(col); // запихали в строку
}
проверим:
т.е. справа в инспекторе даже видно, как меняется разметка. Так как в колонку принято вообще пихать div с классом, то мы можем добавить туда его:
function onButtonClick(btn) {
let newRow = document.getElementById("newRow");
let col = document.createElement("div")
col.innerText = "Я колонка"
col.className = "col p-2 m-2 bg-warning" // добавил классы к новому элементу, колонку, внешние и внутренние отступы и желтый фон
newRow.appendChild(col)
}
тестируем:
Так как я сделал поле для ввода, логично было бы его поиспользовать. Сделаем так чтобы текст с этого поля использовался при генерации очередной колонки. Например, если я введу “верблюд” то в колонку попадет “Я верблюд”, сделать это очень просто:
<div class="container p-2">
<div class="row">
<div class="col">
<!-- добавили id="name" полю для ввода -->
<input id="name" type="text" class="form-control">
</div>
<div class="col-auto">
<!-- ... -->
</div>
</div>
<div id="newRow" class="row"></div>
</div>
<script>
function onButtonClick(btn) {
let name = document.getElementById("name"); // получили поле для ввода по id
let newRow = document.getElementById("newRow");
let col = document.createElement("div")
// формирую фразу, тут используются апострофы ` а не кавычки
// за счет этого вместо ${name.value} подставляется значение поля для ввода
// в большинстве случаем это читабельнее, чем писать: "Я " + name.value
col.innerText = `Я ${name.value}`;
col.className = "col p-2 m-2 bg-warning"
newRow.appendChild(col)
}
</script>
тестируем:
в принципе же просто?)
Короче, теперь можно задание пилить! =О