Сегодня у нас проект по автоматизации: будем ускорять то, что мы делаем в журнале каждый день. Если вы делаете что-то похожее — тоже можете такое автоматизировать.
Предыстория
У нас есть рубрика «Новости» — там наши коллеги каждый день публикуют заметки о технологических и научных новинках.
Раньше процесс был устроен так:
- Каждый автор «пылесосит» свои источники.
- Авторы делают подборки событий и изобретений, о которых можно написать.
- Авторы присылают подборки дежурному редактору рубрики. Тот принимает решение, какие новости стоит взять в «Код», а какие — нет.
- Авторы пишут новости.
- Дежурный редактор проверяет и доделывает новости.
Основной затык с п. 3 — если редактор затупил или долго не отвечает, редакционный процесс может встать.
Чтобы решить эту проблему, в редакции сделали чеклист — он формализует процесс принятия решений по новостям.
В нём всё хорошо, кроме одного — каждый раз нужно самому вручную считать, сколько плюсов и минусов набрала каждая новость. Кажется, что это можно автоматизировать и получать результат по каждой новости гораздо быстрее.
Что будем делать
Самый простой способ решить эту задачу — сделать веб-страницу с вариантами ответов. Вы выбираете нужные и получаете ответ: стоит эту новость брать или нет.
В чек-листе у нас есть значки: ✅ и ❌. Пусть галочка обозначает плюс 1 балл, а крестик — минус 1 балл. За каждый ответ мы прибавляем или отнимаем нужное количество баллов и смотрим на результат.
Чтобы понять, брать новость или нет, сделаем такую градацию:
- если новость набирает отрицательное количество баллов, то точно не берём;
- если сумма баллов равна нулю — переспросить шефа;
- если новость набрала один балл, то всё решают картинки или видео — если они есть, то новость тоже есть;
- если у новости в сумме 2 балла и выше — однозначно берём в работу.
Выбираем варианты ответов
Нам понадобятся переключатели — специальные поля, где можно выбрать только один из нескольких вариантов. Выглядят они так:
Синяя точка означает, что мы выбрали первый вариант. Если выберем второй, то на первом она автоматически снимется:
За такой переключатель в HTML отвечает элемент <input>
со свойством type="radio"
. Чтобы поставить его на страницу, пишут так:
<input name="result" type="radio" value="2">
Последнее свойство value отвечает за результат — какой ответ мы получим, если выберем этот вариант. Двойка у нас получилась от того, что в чек-листе напротив этого ответа стояло две галочки. Если бы было два крестика, мы бы написали value="-2"
.
Теперь у нас есть всё, чтобы оформить первый вопрос в виде кода на HTML:
<!-- Заголовок вопроса -->
<p><b>
Это результат или мысли?
</b></p>
<!-- Абзац, который состоит из переключателя и текста -->
<!-- У каждого ответа есть свой рейтинг, он записан в значение value -->
<p><input name="result" type="radio" value="2">
Что-то изобрели, получили результаты исследования, ключевое слово — результаты
</p>
<!-- Дальше всё то же самое -->
<p>
<input name="result" type="radio" value="-1">
Только думают, планируют, размышляют
</p>
<p><input name="result" type="radio" value="-2">
Статья-обзор, как кто-то фантазирует о будущем
</p>
<br>
Мы сделали три переключателя с одинаковым именем result. Это нужно для того, чтобы браузер понимал, что все три ответа относятся к одному вопросу и нужно выбрать один из них. Если бы мы везде поставили разные имена для свойстваname
, то можно было бы выбрать все три одновременно, а нам это не нужно.
Получается, что для остальных вопросов нам нужно сделать то же самое, только поставить уникальный параметр name
для каждой группы вопросов и проследить за баллами за ответы:
<p><b>
Это прорыв для человека?
</b></p>
<p><input name="mega" type="radio" value="-2">
Что-то существующее немного улучшат с помощью технологий
</p>
<p><input name="mega" type="radio" value="1">
Что-то существующее выведут на новый уровень с помощью технологий
</p>
<p><input name="mega" type="radio" value="2">
Речь о чём-то, что резко повышает качество жизни человека
</p>
<p><input name="mega" type="radio" value="-2">
Речь о чём-то, что в первую очередь поможет учёным или исследователям
</p>
<br>
<p><b>
Это на хайпе?
</b></p>
<p><input name="hype" type="radio" value="1">
Новость про публичную фигуру: Маска, Безоса и т. д.
</p>
<p><input name="hype" type="radio" value="2">
Это касается сервисов или продуктов, доступных в России
</p>
<p><input name="hype" type="radio" value="2">
Это сделано или будет использоваться в России
</p>
<p><input name="hype" type="radio" value="-3">
Это касается продуктов или сервисов, которых нет в России? Алекса, например
</p>
<br>
<p><b>
Можно посмотреть?
</b></p>
<p><input name="see" type="radio" value="3">
Есть красивая картинка или видео, где демонстрируются результаты работы
</p>
<p><input name="see" type="radio" value="-1">
У учёных есть идея, но пока нет картинок. Или есть картинка, но это скорее график
</p>
<p><input name="see" type="radio" value="1">
Эта картинка демонстрирует конкретно то, что изобрели?
</p>
<p><input name="see" type="radio" value="-1">
То, что изобрели, невозможно продемонстрировать как таковое, например, это скрытый алгоритм
</p>
<br>
Добавляем кнопку подсчёта баллов
Добавим на страницу кнопку, по нажатию на которую запустится скрипт подсчёта баллов:
<button onclick="count()"> Оценить </button>
К кнопке привязан обработчик событий onclick — он следит за нажатиями и запускает нужный скрипт. Скрипта у нас ещё нет, поэтому им и займёмся.
Логика будет такая:
- Обнуляем количество отмеченных вопросов и набранных баллов.
- Находим все переключатели на странице.
- Считаем, сколько из них отмечено. Если меньше четырёх (у нас 4 вопроса), то выводим сообщение, что не всё отмечено.
- Для каждого отмеченного считаем, сколько он даёт нам баллов, положительных или отрицательных, и складываем баллы вместе.
- Если у нас есть 4 ответа, то в зависимости от набранных баллов выводим результат.
Чтобы у нас на странице появилась информация с результатами, добавим пустой абзац и пропишем ему своё имя класса. Так мы сможем отличать его от других абзацев. Когда нам что-то понадобится туда поместить, мы найдём его по имени класса и положим в него нужный текст.
Добавим абзац в самый конец страницы:
<!-- В самом низу сделаем пустой абзац, куда будем выводить результаты -->
<p class = "itogo"></p>
Пишем скрипт
В скрипте мы будем использовать три команды, которые нам ещё не встречались, но они довольно простые.
Чтобы не подключать jQuery и при этом находить нужные элементы на странице, используем функцию document.getElementsByClassName("itogo")
. Она найдёт все элементы на странице с указанным классом (itogo) и вернёт массив из найденных элементов. Так как на странице у нас только один такой элемент с таким классом, то это сразу всё упрощает.
Вторая команда — функция document.getElementsByTagName('input')
. Она находит все тэги input и делает из них массив с объектами. Дальше с ними можно уже работать как с обычными элементами — проверять их свойства и значения.
Третье — свойствоgetAttribute()
. С его помощью мы выясним, переключатель перед нами или нет. Если свойство getAttribute('type') совпадает с 'radio', значит это переключатель.
// Функция, которая делает всю работу и срабатывает после нажатия «Оценить»
function count() {
// общее количество баллов
let score = 0;
// Сколько вопросов отмечено
let set = 0;
// Находим элемент на странице, куда будем выводить результат
let el = document.getElementsByClassName("itogo");
// А сюда получаем все элементы ввода, в том числе и переключатели
let inputs = document.getElementsByTagName('input');
// Перебираем все элементы ввода по порядку и смотрим
for (var i = 0; i < inputs.length; i++) {
// Если перед нами — переключатель и он отмечен, то…
if ((inputs[i].getAttribute('type') == 'radio') && (inputs[i].checked == true)) {
// Увеличиваем общее количество отмеченных переключателей
set += 1;
// Обновляем рейтинг для новости: берём значение, переводим его в число и складываем
score = score + Number(inputs[i].getAttribute('value'));
}
}
// Если есть ответы на все 4 вопроса
if (set == 4) {
// то смотрим на рейтинг и выводим итоговый вердикт, а в скобках — сколько баллов набрала новость
if (score < 0) { el[0].innerHTML = 'Не берём (' + score + ')' };
if (score == 0) { el[0].innerHTML = 'Ни туда, ни сюда (' + score + ')' };
if (score == 1) { el[0].innerHTML = 'Если есть картинки — берём (' + score + ')' };
if (score > 1) { el[0].innerHTML = 'Точно берём (' + score + ')' };
}
// А если какой-то вопрос пропустили, то так и пишем
else {
el[0].innerHTML = 'Отмечены не все вопросы';
}
}
Сбрасываем ответы
Чтобы не путаться, добавим кнопку сброса. Она уберёт все отмеченные варианты, и следующую новость можно оценивать заново:
<button onclick="clear()"> Сбросить </button>
Для функции clear() мы возьмём код из предыдущей функции и немного его поправим:
// Сброс ответов
function clearall() {
// Получаем все элементы ввода, в том числе и переключатели
let inputs = document.getElementsByTagName('input');
// Перебираем все элементы ввода по порядку и смотрим
for (var i = 0; i < inputs.length; i++) {
// Если перед нами — переключатель, то…
if (inputs[i].getAttribute('type') == 'radio') {
// …сбрасываем его
inputs[i].checked = false;
}
}
// Находим элемент на странице, куда будем выводить результат
let el = document.getElementsByClassName("itogo");
// Очищаем абзац с результатами
el[0].innerHTML = '';
}
Если вам пока этот сервис не нужен, можно просто посмотреть готовый результат.
Что дальше
Кажется, что проблема решена, но на самом деле нет, смотрите:
- неудобно прицеливаться в маленькие кружочки переключателей, это долго и раздражает
- кнопки тоже маленькие
- результат нужно читать, а это тоже время
- сами вопросы сейчас не заточены под быструю работу с интерфейсом, их нужно переформулировать
- для результата нужно нажать на кнопку, хотя можно сделать автоматический вывод итогов, когда всё отмечено
Всё это сделаем в следующий раз. Не переключайтесь.
<html>
<!-- служебная часть -->
<head>
<!-- заголовок страницы -->
<title>Отбор новостей</title>
<!-- настраиваем служебную информацию для браузеров -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- закрываем служебную часть страницы -->
</head>
<script type="text/javascript">
// Функция, которая делает всю работу и срабатывает после нажатия «Оценить»
function count() {
// общее количество баллов
letscore = 0;
// Сколько вопросов отмечено
letset = 0;
// Находим элемент на странице, куда будем выводить результат
letel = document.getElementsByClassName("itogo");
// А сюда получаем все элементы ввода, в том числе и переключатели
letinputs = document.getElementsByTagName('input');
// Перебираем все элементы ввода по порядку и смотрим
for (var i = 0; i < inputs.length; i++) {
// Если перед нами — переключатель, и он отмечен, то…
if ((inputs[i].getAttribute('type') == 'radio') && (inputs[i].checked == true)) {
// Увеличиваем общее количество отмеченных переключателей
set += 1;
// Обновляем рейтинг для новости: берём значение, переводим его в число и складываем
score = score + Number(inputs[i].getAttribute('value'));
}
}
// Если есть ответы на все 4 вопроса
if (set == 4) {
// то смотрим на рейтинг и выводим итоговый вердикт, а в скобках — сколько баллов набрала новость
if (score < 0) { el[0].innerHTML = 'Не берём (' + score + ')' };
if (score == 0) { el[0].innerHTML = 'Ни туда, ни сюда (' + score + ')' };
if (score == 1) { el[0].innerHTML = 'Если есть картинки — берём (' + score + ')' };
if (score > 1) { el[0].innerHTML = 'Точно берём (' + score + ')' };
}
// А если какой-то вопрос пропустили, то так и пишем
else {
el[0].innerHTML = 'Отмечены не все вопросы';
}
}
// Сброс ответов
function clearall() {
// Получаем все элементы ввода, в том числе и переключатели
let inputs = document.getElementsByTagName('input');
// Перебираем все элементы ввода по порядку и смотрим
for (var i = 0; i < inputs.length; i++) {
// Если перед нами — переключатель, то…
if (inputs[i].getAttribute('type') == 'radio') {
// …сбрасываем его
inputs[i].checked = false;
}
}
// Находим элемент на странице, куда будем выводить результат
let el = document.getElementsByClassName("itogo");
// Очищаем абзац с результатами
el[0].innerHTML = '';
}
</script>
<!-- началось содержимое страницы -->
<body>
<!-- Заголовок вопроса -->
<p><b>
Это результат или мысли?
</b></p>
<!-- Абзац, который состоит из переключателя и текста -->
<!-- У каждого ответа есть свой рейтинг, он записан в значение value -->
<p><input name="result" type="radio" value="2">
Что-то изобрели, получили результаты исследования, ключевое слово — результаты
</p>
<!-- Дальше всё то же самое -->
<p><input name="result" type="radio" value="-1">
Только думают, планируют, размышляют
</p>
<p><input name="result" type="radio" value="-2">
Статья-обзор, как кто-то фантазирует о будущем
</p>
<br>
<p><b>
Это прорыв для человека?
</b></p>
<p><input name="mega" type="radio" value="-2">
Что-то существующее немного улучшат с помощью технологий
</p>
<p><input name="mega" type="radio" value="1">
Что-то существующее выведут на новый уровень с помощью технологий
</p>
<p><input name="mega" type="radio" value="2">
Речь о чём-то, что резко повышает качество жизни человека
</p>
<p><input name="mega" type="radio" value="-2">
Речь о чем-то, что в первую очередь поможет учёным или исследователям
</p>
<br>
<p><b>
Это на хайпе?
</b></p>
<p><input name="hype" type="radio" value="1">
Новость про публичную фигуру: Маска, Безоса и т. д.
</p>
<p><input name="hype" type="radio" value="2">
Это касается сервисов или продуктов, доступных в России
</p>
<p><input name="hype" type="radio" value="2">
Это сделано или будет использоваться в России
</p>
<p><input name="hype" type="radio" value="-3">
Это касается продуктов или сервисов, которых нет в России? Алекса, например
</p>
<br>
<p><b>
Можно посмотреть?
</b></p>
<p><input name="see" type="radio" value="3">
Есть красивая картинка или видео, где демонстрируются результаты работы
</p>
<p><input name="see" type="radio" value="-1">
У учёных есть идея, но пока нет картинок. Или есть картинка, но это скорее график
</p>
<p><input name="see" type="radio" value="1">
Эта картинка демонстрирует конкретно то, что изобрели?
</p>
<p><input name="see" type="radio" value="-1">
То, что изобрели, невозможно продемонстрировать как таковое, например, это скрытый алгоритм
</p>
<br>
<!-- Рисуем кнопку, по нажатию на которую запустится подсчёт рейтинга для новости -->
<button onclick="count()"> Оценить </button>
<!-- Кнопка, которая сбрасывает все ответы -->
<button onclick="clearall()"> Сбросить </button>
<!-- Делаем отступ -->
<br>
<!-- В самом низу сделаем пустой абзац, куда будем выводить результаты -->
<p class="itogo"></p>
</body>
</html>