Улучшаем автоматизацию новостей
Автоматизируем новости
Улучшаем автоматизацию новостей

В про­шлый раз мы сде­ла­ли стра­ни­цу, кото­рая помо­га­ет нам при­ни­мать реше­ния по ново­стям. Всё рабо­та­ет, но после исполь­зо­ва­ния мы поня­ли, что поль­зо­вать­ся этим неудобно:

  • пло­хо подо­бран шрифт и раз­мер, из-за чего читать вопро­сы тяжело;
  • слож­но попасть мыш­кой в малень­кий кру­жок для выбо­ра ответа;
  • кноп­ки тоже малень­кие и нахо­дят­ся рядом — лег­ко пере­пу­тать или промахнуться;
  • резуль­тат выво­дит­ся вни­зу, и его тоже нуж­но читать — это так­же отни­ма­ет лиш­нее время;
  • кажет­ся, что доста­точ­но все­го трёх гра­да­ций: берём, не берём и надо поду­мать, при этом неваж­но, сколь­ко точ­но бал­лов набра­ла новость;
  • ино­гда к вопро­су под­хо­дит одно­вре­мен­но несколь­ко отве­тов, а пере­клю­ча­те­ли поз­во­ля­ют выбрать толь­ко один.

Испра­вим это.

Делаем множественный выбор

Сей­час у нас пере­клю­ча­те­ли, кото­рые дают выби­рать толь­ко один ответ из нескольких:

<input name="mega" type="radio" value="-2">

Что­бы сде­лать чек­бок­сы с галоч­кой, кото­рые не зави­сят друг от дру­га, доста­точ­но вез­де в коде и в функ­ци­ях заме­нить "radio" на "checkbox":

<input name="mega" type="checkbox" value="-2">

Выгля­дит это так:

Вто­рое полез­ное свой­ство чек­бок­сов — у каж­до­го из них может быть своё уни­каль­ное имя. Это нам при­го­дит­ся при под­счё­те баллов.

Упрощаем выбор ответов

Сей­час нам всё рав­но нуж­но целить­ся в малень­кие чек­бок­сы, что­бы выбрать пра­виль­ные отве­ты. Но гораз­до про­ще клик­нуть по тек­сту, что­бы выбрать его — он боль­ше и в него лег­че попасть. 

Полу­ча­ет­ся, нам нуж­но напи­сать такой код, что­бы он сра­ба­ты­вал при каж­дом нажа­тии на абзац с вари­ан­том отве­та и отме­чал или уби­рал соот­вет­ству­ю­щий чекбокс. 

У нас малень­кий бое­вой про­ект на колен­ке, поэто­му мы сде­ла­ем это гряз­но и в лоб — поме­стим обра­бот­чик onclick() в каж­дый абзац и будем пере­да­вать ему имя чек­бок­са как параметр:

<p onclick="p_click('result2')"><input name="result2" type="checkbox" value="2">

Есть более валид­ный спо­соб сде­лать это — через тег <label>. Тогда чек­бокс будет знать, где его лей­бл, а лей­бл будет знать, каким чек­бок­сом он управ­ля­ет. Но тогда один лей­бл будет все­гда отве­чать за один чек­бокс. Воз­мож­но, в буду­щем нам пона­до­бит­ся настро­ить более слож­ную логи­ку: напри­мер, при нажа­тии на один абзац отме­ча­ют­ся два чек­бок­са или один вклю­ча­ет­ся, а дру­гой выклю­ча­ет­ся. Этот вари­ант пока отложим. 

Мож­но было бы собрать все абза­цы и в кон­це доку­мен­та с помо­щью скрип­та пове­сить на них обра­бот­чи­ки кли­ков. Но это тоже не даст нам нуж­ной гибкости.

Поэто­му пока оста­но­вим­ся на диком реше­нии в лоб: ско­пи­па­стим обра­бот­чик onclick во все абзацы.

Обработчик

Теперь напи­шем саму функ­цию, кото­рая поста­вит галоч­ку в нуж­ном месте:

// Вызываем эту функцию при каждом клике на ответе
function p_click(name) {
	// Получаем все элементы ввода, в том числе и чекбоксы
	let inputs = document.getElementsByTagName('input');

	// Перебираем все элементы ввода по порядку и смотрим
	for(var i=0; i<inputs.length; i++){

	  // Если перед нами — чекбокс с нужным именем, то…
	  if (inputs[i].getAttribute('name')==name) {
	  	// меняем его значение
		inputs[i].checked = !inputs[i].checked;
	  }
	}

Дизайн и подсветка вариантов

Теперь зай­мём­ся внеш­ним видом стра­ни­цы. Для это­го поме­ня­ем шрифт и уве­ли­чим его раз­мер. А что­бы было про­ще понять, какой вари­ант отве­та мы сей­час выбе­рем, возь­мём код из ста­тьи про кра­си­вые ссыл­ки и при­ме­ним его к абзацам:

/*задаём общие параметры для всей страницы*/
body {
  text-align: left;
  margin: 10;
  font-family: Verdana, Arial, sans-serif;
  font-size: 16px;
}

/*делаем красивые ссылки*/
p {
     text-decoration: none;
     color: #000000;
}

p:hover {
     text-decoration: none;
     color: #cf0000;
     border-bottom-color: rgba(208, 64, 0, 0.2);
}

Убираем кнопки

Про­бле­ма: неудоб­но попа­дать в малень­кие кнопки. 

Иде­аль­ное реше­ние: сде­лать так, что­бы мож­но было обой­тись вооб­ще без кнопок.

Про­ще все­го изба­вить­ся от кноп­ки «Сбро­сить», кото­рая очи­ща­ет все чек­бок­сы. Для это­го мы сде­ла­ем так, что­бы сброс рабо­тал по двой­но­му кли­ку мыш­ки в любом месте страницы:

<!-- очищаем результаты по двойному клику --> <body ondblclick="clearall()">
// Сброс ответов
function clearall() {

	// Получаем все элементы ввода, в том числе и переключатели
	let inputs = document.getElementsByTagName('input');

	// Перебираем все элементы ввода по порядку и смотрим
	for(var i=0; i<inputs.length; i++){

	  // Если перед нами — переключатель, то…
	  if (inputs[i].getAttribute('type')=='checkbox') {
	  	// …сбрасываем его
			inputs[i].checked = false;
	  }
	}
}

Что­бы изба­вить­ся от кноп­ки «Оце­нить», нам нуж­но вызы­вать функ­цию под­счё­та каж­дый раз, когда мы выби­ра­ем какой-то ответ. Но у нас уже есть функ­ция, кото­рую мы вызы­ва­ем в этом слу­чае — p_click(). Зна­чит, если мы в неё доба­вим вызов функ­ции под­счё­та count(), то кноп­ку мож­но тоже убирать.

Рабо­тать всё это будет так: мы нажи­ма­ем на любой ответ, а скрипт сра­зу пере­счи­ты­ва­ет резуль­та­ты. Если будет что выво­дить — он покажет.

Убираем надпись с результатами

Про­бле­ма: текст с резуль­та­та­ми нуж­но пере­чи­ты­вать каж­дый раз, а это тоже отни­ма­ет время.

Иде­аль­ное реше­ние: сде­лать так, что­бы мож­но было обой­тись вооб­ще без над­пи­си. Напри­мер, при поло­жи­тель­ном реше­нии менять цвет фона на зелё­ный, при нуле­вом — на жёл­тый, а если сум­ма бал­лов отри­ца­тель­ная, то делать его крас­ным. В этом слу­чае нам не нуж­но будет ниче­го читать, но при этом мы будем знать результат.

Для это­го нам пона­до­бит­ся свой­ство document.body.style.background — оно отве­ча­ет за цвет фона всей стра­ни­цы. Если нам нужен белый фон, то коман­да будет выгля­деть так:

document.body.style.background = '#ffffff' 

Зная это, заме­ним коман­ды выво­да тек­ста с резуль­та­том на коман­ду сме­ны фона:

// Если есть хотя бы 4 ответа
if (set >= 4) {
	// то смотрим на рейтинг и красим фон в нужный цвет
	if (score < 0) { document.body.style.background = '#ffc0cb' };
	if (score == 0) { document.body.style.background = '#ffff99' };
	if (score > 0) { document.body.style.background = '#ccffcc' };
// иначе делаем фон снова белым
} else {
	document.body.style.background = '#ffffff' 
}

Послед­нее, что нам оста­лось сде­лать, — доба­вить воз­врат бело­го фона в конец функ­ции сбро­са резуль­та­тов clearall().

Ещё мы умень­ши­ли коли­че­ство гра­да­ций с резуль­та­та­ми, что­бы было про­ще ори­ен­ти­ро­вать­ся. Теперь сра­зу понят­но, что если фон стал зелё­ным, то новость мож­но брать в рабо­ту, а если крас­ным — то, ско­рее все­го, нет.

Гото­вая стра­ни­ца с новым дизай­ном.

Было:

Ста­ло:

Что дальше

Этот код есть куда улучшать:

  • мож­но про­ка­чать дизайн, сде­лать обла­сти более кли­ка­бель­ны­ми и удобными;
  • сде­лать один обра­бот­чик на все нажа­тия на текст;
  • доба­вить настрой­ку бал­лов за ответы;
  • сде­лать исто­рию для ново­стей и их резуль­та­тов с ответами;
  • в кон­це кон­цов, мож­но научить ней­ро­сеть саму ана­ли­зи­ро­вать текст ново­сти и при­хо­дить к нуж­ным выводам.

Будет отлич­но, если вы в ком­мен­та­ри­ях тоже напи­ше­те, что бы вы доба­ви­ли в этот сервис.

Готовый код

<html>

<!-- служебная часть -->
<head>
  <!-- заголовок страницы -->
  <title>Отбор новостей</title>

  <!-- настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <style type="text/css">

    /*задаём общие параметры для всей страницы*/
    body{
      text-align: left;
      margin: 10;
      font-family: Verdana, Arial, sans-serif;
      font-size: 16px;
    }
  
    /*делаем красивые ссылки*/
    p {
         text-decoration: none;
         color: #000000;
    }

    p:hover {
         text-decoration: none;
         color: #cf0000;
         border-bottom-color: rgba(208, 64, 0, 0.2);
    }
    
  /*закончили со стилями*/
  </style>

<!-- закрываем служебную часть страницы -->
</head>

<script type="text/javascript">

  // Функция, которая считает ответы и показывает результат
  function count() {

  	// Сколько вопросов отмечено 
  	let set = 0;

		// общее количество баллов
	  let score = 0;

		// Находим элемент на странице, куда будем выводить результат
		let el = document.getElementsByClassName("itogo");

		// А сюда получаем все элементы ввода, в том числе и переключатели
		let inputs = document.getElementsByTagName('input');

		// Перебираем все элементы ввода по порядку и смотрим
		for(var i=0; i<inputs.length; i++){

		  // Если перед нами — переключатель, и он отмечен, то…
		  if ((inputs[i].getAttribute('type')=='checkbox') && (inputs[i].checked == true)) {

		  // Увеличиваем счётчик ответов
		  set += 1;	
		  
			// Обновляем рейтинг для новости: берём значение, переводим его в число и складываем
			score = score + Number(inputs[i].getAttribute('value'));
		  }
		}

// Если есть хотя бы 4 ответа
if (set >= 4) {
	// то смотрим на рейтинг и красим фон в нужный цвет
	if (score < 0) { document.body.style.background = '#ffc0cb' };
	if (score == 0) { document.body.style.background = '#ffff99' };
	if (score > 0) { document.body.style.background = '#ccffcc' };
// иначе делаем фон снова белым
} else {
	document.body.style.background = '#ffffff' 
}

	}

	// Сброс ответов
	function clearall() {

		// Получаем все элементы ввода, в том числе и переключатели
		let inputs = document.getElementsByTagName('input');

		// Перебираем все элементы ввода по порядку и смотрим
		for(var i=0; i<inputs.length; i++){

		  // Если перед нами — переключатель, то…
		  if (inputs[i].getAttribute('type')=='checkbox') {
		  	// …сбрасываем его
				inputs[i].checked = false;
		  }
		}
		//  делаем фон снова белым
		document.body.style.background = '#ffffff';

	}

	// Вызываем эту функцию при каждом клике на ответе
 	function	p_click(name){
 		// Получаем все элементы ввода, в том числе и чекбоксы
 		let inputs = document.getElementsByTagName('input');

 		// Перебираем все элементы ввода по порядку и смотрим
 		for(var i=0; i<inputs.length; i++){

 		  // Если перед нами — чекбокс с нужным именем, то…
 		  if (inputs[i].getAttribute('name')==name) {
 		  	// меняем его значение
 				inputs[i].checked = !inputs[i].checked;
 		  }
 		}

 		// Пересчитываем оценки
		count();
	}

</script>

<!-- началось содержимое страницы -->
<!-- очищаем результаты по двойному клику -->
 <body ondblclick="clearall()">

	<!-- Заголовок вопроса -->
	<p><b>
	Это результат или мысли?
	</b></p>
	<!-- Абзац, который состоит из чекбокса и текста -->
	<!-- У каждого ответа есть свой рейтинг, он записан в значение value -->
	<p onclick="p_click('result2')"><input name="result2" type="checkbox" value="2">
	Что-то изобрели, получили результаты исследования, ключевое слово — результаты  
	</p>
	<!-- Дальше всё то же самое -->
	<p onclick="p_click('result-1')"><input name="result-1" type="checkbox" value="-1"> 
	Только думают, планируют, размышляют 
	</p>
	<p onclick="p_click('result-2')"><input name="result-2" type="checkbox" value="-2">
	Статья-обзор, как кто-то фантазирует о будущем 
	</p>
	<br>		

	<p><b>
	Это прорыв для человека?
	</b></p>
	<p onclick="p_click('mega-2')"><input name="mega-2" type="checkbox" value="-2">
	Что-то существующее немного улучшат с помощью технологий
	</p>
	<p onclick="p_click('mega1')"><input name="mega1" type="checkbox" value="1"> 
	Что-то существующее выведут на новый уровень с помощью технологий
	</p>
	<p onclick="p_click('mega2')"><input name="mega2" type="checkbox" value="2">
	Речь о чём-то, что резко повышает качество жизни человека
	</p>
	<p onclick="p_click('mega-22')"><input name="mega-22" type="checkbox" value="-2">
	Речь о чём-то, что в первую очередь поможет учёным или исследователям
	</p>
	<br>		

	<p><b>
	Это на хайпе? 
	</b></p>
	<p onclick="p_click('hype1')"><input name="hype1" type="checkbox" value="1">
	Новость про публичную фигуру: Маска, Безоса итд
	</p>
	<p onclick="p_click('hype2')"><input name="hype2" type="checkbox" value="2"> 
	Это касается сервисов или продуктов, доступных в России
	</p>
	<p onclick="p_click('hype22')"><input name="hype22" type="checkbox" value="2">
	Это сделано или будет использоваться в России
	</p>
	<p onclick="p_click('hype-3')"><input name="hype-3" type="checkbox" value="-3">
	Это касается продуктов или сервисов, которых нет в России? Алекса, например. 
	</p>
	<br>	

	<p><b>
	Можно посмотреть?
	</b></p>
	<p onclick="p_click('see3')"><input name="see3" type="checkbox" value="3">
	Есть красивая картинка или видео, где демонстрируются результаты работы
	</p>
	<p onclick="p_click('see-1')"><input name="see-1" type="checkbox" value="-1"> 
	У учёных есть идея, но пока нет картинок. Или есть картинка, но это скорее график
	</p>
	<p onclick="p_click('see1')"><input name="see1" type="checkbox" value="1">
	Эта картинка демонстрирует конкретно то, что изобрели?
	</p>
	<p onclick="p_click('see-11')"><input name="see-11" type="checkbox" value="-1">
	То, что изобрели, невозможно продемонстрировать как таковое, например, это скрытый алгоритм
	</p>
	<br>	
	
 </body>
</html> 

Текст и код:
Миша Поля­нин

Редак­тор:
Мак­сим Ильяхов

Кор­рек­тор:
Ира Михе­е­ва

Иллю­стра­тор:
Даня Бер­ков­ский

Верст­ка:
Маша Дро­но­ва

Соц­се­ти:
Олег Веш­кур­цев

На бла­го:
наше­го новост­но­го отдела