Вывод пунктов меню и текста для них из JSON

121
21 октября 2021, 14:20

Имеется некоторый ветвистый JSON файл. Из него осуществляется вывод пунктов меню. С этим я справился. Но каким способом осуществить вывод данных в зависимости от выбранного пункта меню ?

структура из разряда:

{
    "links" : [
        {
            "linkname" : "link1",
            "linkId" : 0,
            "text" : [
                {
                    "titlename": "1 title of link1",
                    "text": "текст который надо вывести при клике на 1 title of link1"
                },
                {
                    "titlename": "2 title of link1",
                    "text": "текст который надо вывести при клике на 2 title of link1"
                }
            ]
        },
        {
            "linkname" : "link2",
            "linkId"  : 1,
            "text" : [
                {
                    "titlename": "1 title of link2",
                    "text": "текст который надо вывести при клике на 1 title of link2"
                },
                {
                    "titlename": "2 title of link2",
                    "text": "текст который надо вывести при клике на 2 title of link2"
                }
            ]
        }
    ]
}
<aside class="main-content__aside-menu">
</aside>
<ul class="list">
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                  <li>dumb text</li>
                </ul>

document.addEventListener('DOMContentLoaded', function () {
  let menu = document.querySelector('.main-content__aside-menu'),
      list = document.querySelector('.list'),
      textBox = document.querySelector('.text'),
      menuItemList = [],
      titleItemList = [];
  let url = '../data.json';
  let request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
  request.onload = function () {
    if (this.readyState == 4 && this.status == 200) {
      let data = JSON.parse(this.responseText);
      setMenu(menu, data);
      const menuItem = document.querySelectorAll('.menu-item');
      menuItemList = Array.from(menuItem);
      setTitles(list, data, menu, menuItemList);
      const listItem = document.querySelectorAll('.list-item');
      titleItemList = Array.from(listItem);
      setText(textBox, data, list, titleItemList);
    }
  }
  request.send();
});
function setMenu(menu, data) {
  data.links.forEach(function (object) {
    let a = document.createElement('a');
    a.setAttribute('href', '#');
    a.classList.add('menu-item');
    a.innerHTML = object.linkName;
    menu.appendChild(a);
  });
}
function setTitles(list, data, menu, index) {
  menu.addEventListener('click', function (event) {
    let target = event.target.closest('.menu-item'),
        targetIndex = index.indexOf(target),
        linkIndex = 0;   
    list.innerHTML = '';
    data.links.forEach(function (object) {
      if (object.linkId == targetIndex){
        for (let i = 0; i < Object.keys(object.text).length; i++){
          let li = document.createElement('li');
          li.innerHTML = `<a class="list-item" href="#">${object.text[i].textTitle}</a>`;
          list.appendChild(li);
        }
      }
    });
    const listItem = document.querySelectorAll('.list-item');
    titleItemList = Array.from(listItem);
    linkIndex = data.links[targetIndex].linkId;
    console.log(linkIndex);
    setText(list, titleItemList, data, linkIndex);
  });
}
function setText(list, index, data, linkindex) {
  console.log(linkindex);
  list.addEventListener('click', function (event) {
    let target = event.target.closest('.list-item'),
        targetIndex = index.indexOf(target),
        textBox = document.querySelector('.text');
        console.log(linkindex);
    // textBox.innerHTML = `<p>${data.links[linkindex].text[targetIndex].textContent}</p>`;
  });

UPDATE: Теперь проблема в том, что.. почему то в функции setText присваивается несколько переменных. Ну то есть когда вызывается функция setTitles я присваиваю linkIndex значение и это значение передаю в setText. Если клик происходит несколько раз, то передаётся сразу несколько значений. То есть нажму два раза нулевой пункт - выведет 0 0 и в таком духе.

Answer 1

Вызов

menuItem = document.querySelectorAll('.menu-item')

до отработки функции appendJSON вернет пустой список. Т.к. на этот момент никаких элементов в menu нет.

Соответственно вызов

menuItemList = Array.from(menuItem);

вернет пустой массив

Как должно быть:

let menu;
const menuItemList = [];
document.addEventListener('DOMContentLoaded', function() {
  menu = document.querySelector('.main-content__aside-menu');
  getJSON();
});
function appendJSON(data) {
  data.links.forEach(function(object) {
    let a = document.createElement('a');
    a.setAttribute('href', '#');
    a.classList.add('menu-item');
    a.innerHTML = object.linkname;
    menu.appendChild(a);
    menuItemList.push(a);
  });
}

А еще лучше - без глобальных переменных

document.addEventListener('DOMContentLoaded', function() {
  const menu = document.querySelector('.main-content__aside-menu');
  let menuItemList = [];
  let url = '../data.json';
  let request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
  request.onload = function() {
    if (this.readyState == 4 && this.status == 200) {
      let data = JSON.parse(this.responseText);
      appendJSON(menunu, data);
      const menuItem = menu.querySelectorAll('.menu-item');
      menuItemList = Array.from(menuItem);
    }
  }
  request.send();
  menu.addEventListener('click', function(event) {
    let target = event.target.closest('.menu-item');
    console.log(menuItemList.indexOf(target));
  });
});
function appendJSON(menu, data) {
  data.links.forEach(function(object) {
    let a = document.createElement('a');
    a.setAttribute('href', '#');
    a.classList.add('menu-item');
    a.innerHTML = object.linkname;
    menu.appendChild(a);
  });
}
READ ALSO
Иконка для всплывающей подсказки NotifyIcon

Иконка для всплывающей подсказки NotifyIcon

Подскажите, как сделать в WinForms свою иконку для NotiFyIcon, когда есть непрочитанный ShowBaloonTip, как по типу пропущенного звонка на значке с телефоном?...

122
Лаг при Instantiate

Лаг при Instantiate

Когда делаю так:

136
DateTime to int (по мск)

DateTime to int (по мск)

DateTimeNow выводит текущее московское время, но почему при переводе DateTime

213