Счетчик перехода по ссылкам через localStorage

Необходимо создать счетчик перехода по ссылкам через значения localStorage. HTML файл менять нельзя. При нажатии на button должен открываться список с количеством перехода по ссылкам, при повторном нажатии список исчезает и удаляются значения из localStorage.

Мною написан js код, который считывает клики по ссылкам и передает значения в localStorage. Button не кликабельная. В ходе разбирательства понял, что это происходит из-за того, что script подключен в head. Нужно добавить тегу script атрибут defer. Прошу подсказать, как это сделать?

Если вручную прописать тегу script атрибут defer, то кнопка работать будет, но код будет работать неправильно, т.к. при перезагрузке страницы либо при переходе на ссылку Home в localStorage каждое значение будет увеличено на 1 (в моем текущем коде ниже данного бага нет). Прошу подсказать, как это можно устранить?

'use strict';

let setScript = document.getElementsByTagName('script')[2];
setScript.setAttribute('defer', 'defer');
let listData = [
  `You visited Page1 ${Number(localStorage.getItem('Page' + 1))} times`,
  `You visited Page2 ${Number(localStorage.getItem('Page' + 2))} times`,
  `You visited Page3 ${Number(localStorage.getItem('Page' + 3))} times`,
],
listContainer = document.createElement('div'),
listElement = document.createElement('ul'),
numberOfListItems = listData.length,
listItem,
i;

document.getElementsByClassName('container')[0].appendChild(listContainer);
listContainer.appendChild(listElement);


for (i = 0; i < numberOfListItems; ++i) {
  listItem = document.createElement('li');
  listItem.innerHTML = listData[i];
  listElement.appendChild(listItem);
};

listContainer.setAttribute('id', 'hide');
let div = document.getElementById('hide');
div.style.visibility = 'hidden';

function visitLink(path) {
let clicks = localStorage.getItem(path);
localStorage.setItem(path, Number(clicks) + 1);
}
visitLink('Page1');
visitLink('Page2');
visitLink('Page3');


function viewResults() {
  let btn = document.querySelector('.btn-primary'); 

  function openDiv() {
    btn.classList.add('is-open');
    div.style.visibility = 'visible';
  }

  function closeDiv() {
    btn.classList.remove('is-open');
    div.style.visibility = 'hidden';  
    localStorage.removeItem('Page1');
    localStorage.removeItem('Page2');
    localStorage.removeItem('Page3');
  }

  if (btn.classList.contains('is-open')) {
    closeDiv();
  } else {
    openDiv();
  }
}

viewResults();
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://fonts.googleapis.com/css?family=Hind:400,600%7CSource+Sans+Pro:400,600,700%7CFresca"
        rel="stylesheet"/>

  <link rel="stylesheet" type="text/css" href="css/main.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
        integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
          integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
          crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
          integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
          crossorigin="anonymous"></script>

  <script src="js/index.js"></script>

  <title>Homework 6</title>
</head>

<body>
  <div class="container">
    <div class="mx-auto" id="content">
      <ul class="nav nav-pills mt-3 mb-5 ml-5">
        <li class="nav-item">
          <a class="nav-link active" href="#">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" onclick="visitLink('Page1')" href="page_1.html">Page 1</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" onclick="visitLink('Page2')" href="page_2.html">Page 2</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" onclick="visitLink('Page3')" href="page_3.html">Page 3</a>
        </li>
      </ul>
      <h3 class="mb-5">Welcome to Local Storage Homework</h3>
      <button type="button" onclick="viewResults()" class="btn btn-primary btn-lg btn-block mb-5">View page visits results</button>
    </div>

  </div>
</body>


Ответы (2 шт):

Автор решения: Igor

Button не кликабельная.

Button кликабельная.

Нужно добавить тегу script атрибут defer.

Добавить скрипту атрибут defer из этого самого скрипта удавалось только барону Мюнгхаузену.

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://fonts.googleapis.com/css?family=Hind:400,600%7CSource+Sans+Pro:400,600,700%7CFresca" rel="stylesheet" />

  <link rel="stylesheet" type="text/css" href="css/main.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>

  <script src="js/index.js"></script>

  <script>
    window.addEventListener('load', function() {
      let listData = [
          `You visited Page1`, // ${Number(localStorage.getItem('Page' + 1))} times`,
          `You visited Page2`, // ${Number(localStorage.getItem('Page' + 2))} times`,
          `You visited Page3` // ${Number(localStorage.getItem('Page' + 3))} times`,
        ],
        listContainer = document.createElement('div'),
        listElement = document.createElement('ul'),
        numberOfListItems = listData.length,
        listItem,
        i;

      document.getElementsByClassName('container')[0].appendChild(listContainer);
      listContainer.appendChild(listElement);


      for (i = 0; i < numberOfListItems; ++i) {
        listItem = document.createElement('li');
        listItem.innerHTML = listData[i];
        listElement.appendChild(listItem);
      };

      listContainer.setAttribute('id', 'hide');
      let div = document.getElementById('hide');
      div.style.visibility = 'hidden';

      visitLink('Page1');
      visitLink('Page2');
      visitLink('Page3');

      viewResults();
    });

    function visitLink(path) {
      //let clicks = localStorage.getItem(path);
      //localStorage.setItem(path, Number(clicks) + 1);
    }

    function viewResults() {
      let btn = document.querySelector('.btn-primary');
      let div = document.getElementById('hide');

      function openDiv() {
        btn.classList.add('is-open');
        div.style.visibility = 'visible';
      }

      function closeDiv() {
        btn.classList.remove('is-open');
        div.style.visibility = 'hidden';
        //localStorage.removeItem('Page1');
        //localStorage.removeItem('Page2');
        //localStorage.removeItem('Page3');
      }

      if (btn.classList.contains('is-open')) {
        closeDiv();
      } else {
        openDiv();
      }
    }
  </script>

  <title>Homework 6</title>
</head>

<body>
  <div class="container">
    <div class="mx-auto" id="content">
      <ul class="nav nav-pills mt-3 mb-5 ml-5">
        <li class="nav-item">
          <a class="nav-link active" href="#">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" onclick="visitLink('Page1')" href="page_1.html">Page 1</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" onclick="visitLink('Page2')" href="page_2.html">Page 2</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" onclick="visitLink('Page3')" href="page_3.html">Page 3</a>
        </li>
      </ul>
      <h3 class="mb-5">Welcome to Local Storage Homework</h3>
      <button type="button" onclick="viewResults()" class="btn btn-primary btn-lg btn-block mb-5">View page visits results</button>
    </div>

  </div>
</body>

→ Ссылка
Автор решения: Игорь Хар
function visitLink(path) {
    //your code goes here
    let clicks = localStorage.getItem(path);
    localStorage.setItem(path, Number(clicks) + 1);
}

function viewResults() {
    document.querySelector('.is-open') ? document.querySelector('.is-open').remove() : 0 

    let counterList = [
        `You visited Page '1' ${Number(localStorage.getItem(`Page1`))} times`,
        `You visited Page '2' ${Number(localStorage.getItem(`Page2`))} times`,
        `You visited Page '3' ${Number(localStorage.getItem(`Page3`))} times`
    ], listContainer = document.createElement('div'),
    listElement = document.createElement('ul'),listItem 
    
    listContainer.classList.add('is-open');

    document.getElementsByClassName('container')[0].appendChild(listContainer);
    listContainer.appendChild(listElement);

    for (let i = 0; i < counterList.length; i += 1) {
        listItem = document.createElement('li');
        listItem.insertAdjacentHTML('beforeend', counterList[i]); 
        listElement.appendChild(listItem); 
    }
}

При клике на кнопку подразумевается следующие действия:

  • нажали - открылся список с переходом по ссылкам (js добавил в html div со значениями),
  • нажали еще раз - закрылся список удалился и значения остались (js удалил в html div со значениями, но в локал сторидж они остались).

При следующем клике на кнопку откроется список с переходом по ссылкам со значениями записанными в локал сторидж

→ Ссылка