Итеративная печать словаря объектов JavaScript в блоки HTML

Я был бы признателен за помощь в итеративном создании нижележащего div на основе количества элементов в словаре Javascript.

    <div class = "container" style = "padding-bottom: 10px;">
        <div class = "dropdown" style = "padding: 10px;">
            <a href = "#">TOP 3 PS5 HEADSETS<i class = "fa fa-chevron-down"></i>
            </a>
            <ul>
                <div id = "links">

                    <center>
                        <p>3: &darr; INSERT TITLE FOR STEELSERIES &darr;</p>
                    </center>
                    <div class = "product">
                        <img src = "img/products/h-steelseries.png">
                        <a class = "link" href = "INSERT LINK HERE">Read More</a>
                    </div>

                    <center>
                        <p>3: &darr; INSERT TITLE FOR OTHER&darr;</p>
                    </center>
                    <div class = "product">
                        <img src = "img/products/h-other.png">
                        <a class = "link" href = "INSERT LINK HERE">Read More</a>
                    </div>
                </div>
            </ul>
        </div>
    </div>

Ниже находится файл read.js, содержащий элементы, для которых я хочу сгенерировать "продукт" класса div.

Я действительно хотел бы помочь с этим.

var prod_obj = {
    "headphone_products" : {
        "title": "Steelseries",
        "IMAGE": "h-steelseries.png",
        "HREF" : "steelseries.html"
},
"other_products" : {
    "title": "Other product",
    "IMAGE": "h-other.png",
    "HREF" : "other.html"
}
};

Я просмотрел другие ответы и не смог найти пример словаря объектов, который использовался для автоматического создания div. Я намереваюсь использовать это для перечисления элементов на веб-сайте и хотел бы добавить объекты в словарь, чтобы они автоматически генерировали новый div для каждого объекта после выполнения сценария.

Спасибо за ваше время.

Это все, что есть в HTML - он не будет повторяться, и вы просто хотите заполнить его значениями в данных json?

Professor Abronsius 09.04.2021 10:01

@ProfessorAbronsius извиняюсь, я бы хотел, чтобы результат был именно таким. Я бы хотел, чтобы этот div был сгенерирован для второго объекта в словаре и т. д.

my name jeff 09.04.2021 10:02

Значит, это будет повторяться N раз? Если это так, то проблема заключается в идентификаторе links.

Professor Abronsius 09.04.2021 10:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
43
4

Ответы 4

Вы можете просто перебрать объект и создать нужные узлы внутри цикла.

Вот более простая версия того же самого.

var prod_obj = {
  "headphone_products": {
    "title": "Steelseries",
  },
  "other_products": {
    "title": "Other product",
  }
};

for (let keys in prod_obj) {
  const div = document.createElement("div");
  div.innerText = prod_obj[keys].title
  document.body.appendChild(div)
}

Вы можете использовать циклы for-in и литералы шаблонов для достижения желаемого.

const prod_obj = {
  "headphone_products": {
    "title": "Steelseries",
    "image": "h-steelseries.png",
    "href": "steelseries.html"
  },
  "other_products": {
    "title": "Other product",
    "image": "h-other.png",
    "href": "other.html"
  }
};

const div = document.getElementById('insertHere');

for (let products_key in prod_obj) {
  let {title, image, href} = prod_obj[products_key];
  let html = `<p>Title: ${title}, Image: ${image}, href: ${href}</p>`;
  div.insertAdjacentHTML('beforeend', html);
}
<div id = "insertHere">
</div>

То, что вы описываете, звучит как подходящий кандидат на шаблон, который, согласно документации по MDN, гласит:

The HTML Content Template () element is a mechanism for holding HTML that is not to be rendered immediately when a page is loaded but may be instantiated subsequently during runtime using JavaScript.

В следующем примере используется простой класс для загрузки нового экземпляра назначенного шаблона для каждого продукта, обнаруженного в исходных данных (то, что вы называете dictionary). После того, как шаблон загружен из теней, вы можете манипулировать содержимым по своему усмотрению. Если вы измените дизайн шаблона, вы измените дизайн окончательного макета. В исходном HTML нет элемента span, окружающего отдельные продукты, но способ, которым я написал загрузчик шаблонов (для конкретной работы), полностью клонирует дочерний элемент first, поэтому span не повлияет на макет, если специально для этого не задан стиль.

class TemplateLoader{
  constructor( id ){
    this.id=id;
    return this.create();
  };
  gettemplate(){
    return document.querySelector( 'template[ data-id = "'+this.id+'" ]' ) || false
  };
  clone(){
    let tmpl=this.gettemplate();
    return tmpl ? tmpl.content.firstElementChild.cloneNode( true ) : false;
  };
  gettarget(){
    return document.querySelector( 'div[ id = "'+this.id+'" ]' ) || false;
  };
  create(){
    let tmpl=this.clone();
    if ( tmpl ){
      let target=this.gettarget();
        target.appendChild( tmpl );
      return tmpl;
    }
    return false;
  };
};

  var prod_obj = {
    'headphone_products' : {
      'title': 'steelseries',
      'image': 'h-steelseries.png',
      'href' : 'steelseries.html'
    },
    'other_products' : {
      'title': 'other product',
      'image': 'h-other.png',
      'href' : 'other.html'
    },
    'banana':{
      'title':'curvy & yellow',
      'image':'b-a-nana.png',
      'href':'banana.html'
    }
  };

  let id='links';

  Object.keys( prod_obj ).forEach( cat => {
    let data=prod_obj[ cat ];

    let oTmpl=new TemplateLoader( id );
      oTmpl.querySelector('center > p').textContent=data.title;
      oTmpl.querySelector('div.product > img').src=['img/products',data.image].join('/');
      oTmpl.querySelector('div.product > a.link').href=data.href;
  });
<!-- regular HTML -->
<div class='container'>
  <div class='dropdown'>
    <a href='#'>TOP 3 PS5 HEADSETS<i class='fa fa-chevron-down'></i></a>
    <ul>
      <div id='links'>
        <!-- items will be populated here -->
      </div>
    </ul>
  </div>
</div>








<!-- our template that will be used to generate new content within the above, regular HTML' -->
<template data-id='links'>
  <span>
    <center>
      <p></p>
    </center>
    <div class='product'>
      <img />
      <a class='link'>Read More</a>
    </div>
  </span>
</template>

Это великолепно. Приносим извинения за двойной пост - я отправил его со своего ноутбука, так как мой компьютер был с синим экраном, и я не смог найти этот пост. Это моя ошибка, но я случайно разместил не тот словарь - тот, что во втором посте, был правильным вложением.

my name jeff 09.04.2021 11:40

В сообщении "other" структура данных сильно отличается от показанной здесь. Как эта структура должна использоваться с данным HTML здесь? В этих новых данных нет ссылок на изображения - теперь они избыточны?

Professor Abronsius 09.04.2021 12:00

В качестве примера я использовал ссылки на изображения. Мне это просто нужно, чтобы я мог добавлять дополнительные значения к объектам, если захочу в будущем.

my name jeff 09.04.2021 12:11

Непонятно, как ваша новая структура данных должна работать с учетом вышеизложенного. Имеет ли значение, что существует несколько объектов верхнего уровня, каждый из которых содержит продукты - должен ли каждый продукт быть добавлен, как раньше, или существуют особые требования в отношении макета. Это четко не определено.

Professor Abronsius 09.04.2021 15:31

Между прочим, я только что заметил, что ваша разметка ошибочна ... Вы не можете вложить div в качестве прямого дочернего элемента элементов ul, но можно вложить элементы div в элемент li

Professor Abronsius 09.04.2021 16:17

Традиционный способ добавления содержимого в DOM на лету - использовать серию вызовов createElmenent и appendChild (что менее подвержено ошибкам, чем простая вставка строк HTML). И вы можете пройтись по ключам вашего объекта данных и извлечь детали вам нужно настроить ваши новые элементы DOM. Этот сценарий выполняет обе эти функции в функции updateDOM, которая вызывает функцию appendProductDetails один раз для каждого продукта.

Я изменил hrefs, чтобы создать функциональные (если произвольные) ссылки, и, конечно же, изображения не отображаются, потому что они не существуют на сервере StackOverflow. См. Комментарии в коде для дальнейшего объяснения.

const currentProds = getProductsToShow();
updateDOM(currentProds);

function updateDOM(prod_obj) {

  // Identifies parent div
  const linksDiv = document.getElementById("links");

  // Clears parent div
  linksDiv.innerHTML = "";

  // Loops through productName (keys) in prod_obj
  const productNames = Object.keys(prod_obj);
  for (let productName of productNames) {

    // Gets details (inner object) for each product
    const details_obj = prod_obj[productName];

    // Creates, configures, and appends new elements for each product
    appendProductDetails(linksDiv, details_obj);
  }
}

function appendProductDetails(parentElement, detailsObject) {
  const
  // Gets local copies of values via "destructuring"
  { title, image, href } = detailsObject,
  path = "img/products/", // Defines path to images

    // Creates elements to add to the DOM
    productDiv = document.createElement("div"),
    titleP = document.createElement("p"),
    img = document.createElement("img"),
    anchor = document.createElement("a");

  // Configures newly created elements
  productDiv.classList.add("product");
  titleP.textContent = title;
  img.src = path + image;
  img.alt = image;
  anchor.classList.add("link");
  anchor.href = href;
  anchor.textContent = "Read More";

  // Puts children into productDiv
  productDiv.appendChild(titleP);
  productDiv.appendChild(img);
  productDiv.appendChild(anchor);

  // Attaches everything to the DOM
  parentElement.appendChild(productDiv);
}

// Provides demo data
function getProductsToShow() {
  const productsObj = {
    "headphone_products": {
      "title": "Steelseries",
      "image": "h-steelseries.png", // In img/products/
      "href": "https://stackoverflow.com"
    },
    "other_products": {
      "title": "Other product",
      "image": "h-other.png",
      "href": "https://eloquentjavascript.net/"
    }
  };
  return productsObj;
}
.container{ width: 250px; text-align: center; }
.dropdown > a{ text-decoration: none; }
p{ margin: -0.1rem 0; font-size: 1.2rem; }
.product{ padding: 0.5rem ; }
.link{ margin-left: 1rem; }
<div class = "container">
  <div class = "dropdown">
    <a href = "#">PS5 HEADSETS</a>
    <div id = "links"></div>
  </div>
</div>

(Более современный подход заключался бы в многократном клонировании содержимого элемента template и использовании элементов slot для вставки соответствующих сведений о продукте в каждый новый экземпляр.)

Другие вопросы по теме