Counting quiz for children I made a game for children. This game tests the ability to count (i.e. compare numbers based on magnitude). First you must select the age of the child in the upper menu, then you need to select blocks with numbers in ascending order.

JSFIDDLE



document.addEventListener("DOMContentLoaded", ready);

let currNum;
let step;
let startContent = 'Это простейший тренажёр для детей, он проверяет способность считать. Предполагается, что: \
&lt;br&gt;дети от 1 до 3 лет должны уметь считать до 5 \
&lt;br&gt;дети от 4 до 5 лет должны уметь считать до 10 \
&lt;br&gt;дети от 6 до 7 лет должны уметь считать до 30 \
&lt;br&gt;дети от 7 до 9 лет должны уметь считать до 100 \
 &lt;br&gt;&lt;br&gt;Чтобы проверить знания участнику предлагается последовательно в порядке возрастания выбрать кубики с цифрами \
';

function init() {
 currNum = -1;
 step = 0
 let startBtn = document.getElementById('start');
 startBtn.click();
};

function clearContent() {
 let contentInner = document.getElementById('contentInner');
 contentInner.innerHTML = '';
};

function deletePoint(id) {
 let pointEl = document.getElementById(id);
 pointEl.parentNode.removeChild(pointEl);
};

function createPoints(count) {
 let contentInner = document.getElementById('contentInner');

 for(let i = 0; i &lt;= 2; i++) {
  let num_ = Math.random() * count;
  let num = Math.ceil(num_);

  let pointEl = document.createElement('div');
  pointEl.className = 'point';
  pointEl.id = 'point_' + i;
  pointEl.setAttribute('data-num', num);
  pointEl.innerHTML = num;  

  contentInner.appendChild(pointEl);
 };
};


function ready() {
 let ulEl = document.getElementById('ul');
 let contentInnerEl = document.getElementById('contentInner');

 let menu = Rx.Observable.fromEvent(ulEl, 'click');
 let contentInner = Rx.Observable.fromEvent(contentInnerEl, 'click');

 let subscription = menu
 .map(e =&gt; e.target)
 .filter(t =&gt; t.className === 'start' || t.className === 'li')
 .subscribe(function (t) {
  clearContent();
    switch (t.className) {
      case 'start':
    document.getElementById('contentInner').innerHTML = startContent;
        break;
      case 'li':    
    createPoints(t.getAttribute('data-count'));
        break;
    }
 });

 let subscription3 = contentInner
 .map(e =&gt; e.target)
 .filter(t =&gt; t.className === 'point')
 .subscribe(function (t) {
  let val = +document.getElementById(t.id).innerHTML;

  ++step;
  deletePoint(t.id);

  if(currNum &gt; val) { 
   alert('Not correct'); 
   init();
  } else {
   currNum = val;
   if(step &gt; 2) { 
    alert('Correct'); 
    init();
   }
  } 
 });         
 
 init();
};
&lt;script src="https://unpkg.com/rxjs@5.5.2/bundles/Rx.min.js"&gt;&lt;/script&gt;
&lt;ul class="ul" id="ul"&gt;
    &lt;li class="li" id="link_0" data-count="5"&gt;1-3&lt;/li&gt;
    &lt;li class="li" id="link_1" data-count="10"&gt;4-5&lt;/li&gt;
    &lt;li class="li" id="link_2" data-count="30"&gt;6-7&lt;/li&gt;
    &lt;li class="li" id="link_3" data-count="100"&gt;7-9&lt;/li&gt;
    &lt;li class="start" id="start"&gt;start&lt;/li&gt;
&lt;/ul&gt;   

&lt;div class="content" id="content"&gt;
    &lt;div class="content-inner" id="contentInner"&gt;&lt;/div&gt;
&lt;/div&gt;
First off I noticed a problem in how the quiz chooses the numbers:


It can easily happen that two (or more) numbers are the same. Especially when picking number between 1..5. In that case it can be confusing to the user, which of the two equal numbers should he click.


The main problems with the code resides in tight coupling between UI logic and business logic. For example the createPoints() function:

function createPoints(count) {
    let contentInner = document.getElementById('contentInner');

    for(let i = 0; i &lt;= 2; i++) {
        let num_ = Math.random() * count;
        let num = Math.ceil(num_);

        let pointEl = document.createElement('div');
        pointEl.className = 'point';
        pointEl.id = 'point_' + i;
        pointEl.setAttribute('data-num', num);
        pointEl.innerHTML = num;

        contentInner.appendChild(pointEl);
    };
};


This function both:


generates three random numbers and
displays the numbers on page.


Would be better two have two functions that separately perform the tasks, something that could be used like so:

displayNumbers(randomNumbersBelow(10))


Also note the naming: the original name createPoints() seems to be talking about some coordinates, which doesn't sound correct to me.

By separating the two, it should be also easier to improve randomNumbersBelow() function so that it would not return duplicates, without having to modify anything inside displayNumbers().

Additionally:


num_ variable can be easily eliminated by inlining the expression: Math.ceil(Math.random() * count).
Instead of modifying the contentInner element by itself, it could just return the new contents (e.g. as a DocumentFragment). That would eliminate the need for the existence of clearContent() function.