Как клонировать или создать вложенный узел DOM и изменить все содержащиеся в нем значения идентификатора в соответствии с текущим идентификатором?

Мне нужно отобразить некоторые числа, строки из класса с именем Student, но я не могу понять, как я могу изменить идентификатор из дочернего элемента. Я должен использовать JavaScript.

что я пытался сделать:

class Student{
    static count = 0;
    constructor(nume, prenume, data_nasterii, foaie_matricola){
        this.IdClasa = ++Student.count;
        //definirea atributelor
        this.nume = nume; 
        this.prenume = prenume;
        this.data_nasterii = data_nasterii;
        this.foaie_matricola = foaie_matricola;
    }
    afiseazaVarsta(){
    
    }
    afiseazaNotele(){
        
    }
    calculeazaMedia(){
        
    }
    adaugaNota(nota_noua){
        
    }
}
var Stud = [new Student("Name", "Name1", "2000.01.01", "0123123"), 
            new Student("Green", "Blue", "2022/12.12", "321321")];

function afisareStudenti(){
    let i = 0; let bol = false;
    for(let x=1; x<=Student.count; x++) {
        console.info(document.getElementById("AfisareStudenti"+x)==null);
        if (document.getElementById("AfisareStudenti"+x)==null)
        {
            i = x;
            bol = true;
            break;
        } else {
            bol = false;
        }
            
    }
    

    if ((i<=Student.count)&&(bol==true)){
        for(i; i<=Student.count; i++) {
            console.info("i = "+i);
            var div = document.querySelector('#AfisareStudenti1');
            var divClone = div.cloneNode(true);
            console.info(divClone);
            divClone.id = 'AfisareStudenti'+(i);
            div.after(divClone);
            var NumeStud = document.getElementById("NumeStudent"+(i-1));
            var PrenumeStud = document.getElementById("PrenumeStudent"+(i-1));
            var dataNastStud = document.getElementById("intData"+(i-1));
            var FoaiaMatStud = document.getElementById("FoaiaMatStud"+(i-1));
            NumeStud.id = "NumeStudent"+(i);
            PrenumeStud.id = "PrenumeStud"+(i);
            dataNastStud.id = "intData"+(i);
            FoaiaMatStud.id = "FoaiaMatStud"+(i);
        }
    }
}

и это файл html (div, который я хочу клонировать):

<!--AFISARE-->
<div id = "AfisareStudenti1">
    <h2> Afisare Student 1</h2>
    <label>Ce student doriti sa modificati?&emsp;</label>
    <form>
          <label>Nume:</label><br>
          <input type = "text" id = "NumeStudent1"><br>
          
          <label>Prenume:</label><br>
          <input type = "text" id = "PrenumeStudent1"><br>
          
          <label>Data Nasterii:</label><br>
          <input type = "date" id = "intData1"><br>
          
          <label>Foaie matricola:</label><br>
          <input type = "text" id = "FoaiaMatStud1"><br><br>
          
          <input class = "butoane" type = "submit" value = "Afisare"
                 onclick = "afisareMeniuAfisStudenti()">
    </form>
</div>

класс сохраняется в динамическом массиве (может быть n объектом класса), поэтому мне нужно как-то сделать динамическое отображение информации. Моя версия изменяет идентификатор всех элементов с одним и тем же идентификатором (каждое приращение i, также увеличивается идентификатор из идентификатора). Я пытался создать этот div с помощью document.createElement, но это невозможно (по крайней мере, для меня) xD. Я начал программировать на javascript 2 дня назад, поэтому, пожалуйста, не торопитесь :(

Я думаю, что нашел проблему, но это не решает ее. (мне нужно поставить (i-1) при вызове для получения идентификаторов). (ошибка новичка)

Вопрос ... какие значения ('AfisareStudenti1', 'AfisareStudenti2', ...) атрибутов id подходят для чего-либо? Если возможно, ОП должен избавиться от него. Это также упрощает процесс клонирования. В случае, если причиной был запрос студенческих предметов. Можно было бы использовать общее имя класса, такое как 'student-item', где можно было бы получить доступ к списку узлов студенческих элементов, таких как ... document.querySelectorAll('.student-item')... и получить доступ к каждому студенческому элементу по его индексу (0, 1, 2, ...).

Peter Seliger 07.12.2022 17:37

Я буду использовать это, чтобы скрыть div. Не знаю, надежно ли скрывать их по одному :) А мне было проще скопировать весь div. По крайней мере для меня.

AmicuLL 07.12.2022 17:43

по-прежнему нет необходимости в id ... можно получить доступ к каждому элементу ученика через его индекс списка узлов, чтобы скрыть его.

Peter Seliger 07.12.2022 17:45

я пытаюсь понять, что вы там сказали... Список узлов? Он возвращает массив индексов? Я знаю, как кодировать на java, c++, но javascript, похоже, сильно отличается...

AmicuLL 07.12.2022 17:53

Взгляните еще раз на мой 1-й комментарий, а затем на документацию, например. MDN Web API и там в querySelectorAll и NodeList ... например. скрытие первого узла предмета ученика... const listOfStudentItems = document.querySelectorAll('.student-item'); listOfStudentItems[0].style.display = 'none';

Peter Seliger 07.12.2022 17:58

OP не показывает весь код... например. что делает глобальная функция afisareMeniuAfisStudenti (displayStudentsMenu)? Как он получает правильную/текущую информацию/данные об элементе учащегося. Кроме того, кто отвечает за вызов функции afisareStudenti (displayStudents)? У меня такое ощущение, что, если бы аудитория получила более широкую картину, она могла бы оказать гораздо большую помощь, поскольку ОП можно было бы вернуть с более компактными / более чистыми и более удобными подходами.

Peter Seliger 07.12.2022 18:20
Поведение ключевого слова "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) для оценки ваших знаний,...
0
6
110
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Чтобы изменить атрибут id дочерних элементов, вы можете использовать Element.querySelector() на divClone.

Потому что, если вы используете Document.querySelector() или Document.getElementById(), вы получите первый элемент, который соответствует вашему селектору (т.е. потомки div#AfisareStudenti1).

let i = 2;
var div = document.querySelector('#AfisareStudenti1');
var divClone = div.cloneNode(true);
divClone.id = 'AfisareStudenti'+(i);
divClone.querySelector("h2").innerText = "Afisare Student " + i;
var NumeStud = divClone.querySelector("#NumeStudent1");
var PrenumeStud = divClone.querySelector("#PrenumeStudent1");
var dataNastStud = divClone.querySelector("#intData1");
var FoaiaMatStud = divClone.querySelector("#FoaiaMatStud1");
NumeStud.id = "NumeStudent"+(i);
PrenumeStud.id = "PrenumeStud"+(i);
dataNastStud.id = "intData"+(i);
FoaiaMatStud.id = "FoaiaMatStud"+(i);
div.after(divClone);
<div id = "AfisareStudenti1">
  <h2> Afisare Student 1</h2>
  <label>Ce student doriti sa modificati?&emsp;</label>
  <form>
    <label>Nume:</label><br>
    <input type = "text" id = "NumeStudent1" /><br>
    <label>Prenume:</label><br>
    <input type = "text" id = "PrenumeStudent1" /><br>
    <label>Data Nasterii:</label><br>
    <input type = "date" id = "intData1" /><br>
    <label>Foaie matricola:</label><br>
    <input type = "text" id = "FoaiaMatStud1" /><br><br>
    <input class = "butoane" type = "submit" value = "Afisare" onclick = "afisareMeniuAfisStudenti()" />
    </form>
</div>

Я попробовал код... кажется, он отлично работает с двумя объектами... Но если я добавлю более двух, я получаю эту ошибку: Uncaught TypeError: Cannot set properties of null (setting 'id') в этой строке NumeStud.id = "NumeStudent"+(i);

AmicuLL 07.12.2022 17:39

@AmicuLL Да, мой плохой, я отредактировал свой ответ. Вы клонируете div#AfisareStudenti1 каждый раз. Когда i есть 3, divClone.querySelector("#NumeStudent2"); есть null.

Tom 07.12.2022 18:15

Спасибо! Теперь понятно, как это надо делать :)) . Сначала я подумал, что java-скрипты создают элементы мгновенно (это в цикле for, да... я тупой), и когда код начинает менять идентификатор, он меняет их все (сначала код ведет себя так, и я не мог сказать, почему :P)

AmicuLL 08.12.2022 05:25

Ответ Тома выше - это то, что вы хотите для проблемы с идентификатором элемента, о которой вы спрашивали.

В частности, для вашего кода у вас будет пара других проблем:

Поскольку окончательным вводом является type="submit", страница будет перезагружена по умолчанию при нажатии. Имя функции «onclick» также должно соответствовать заданной вами функции (afisareStudenti).

У тебя есть:

<input class = "butoane" type = "submit" value = "Afisare" onclick = "afisareMeniuAfisStudenti()">

Измените это на:

<input class = "butoane" type = "submit" value = "Afisare" onclick = "afisareStudenti(event)">

Теперь, когда вы нажмете эту кнопку, она вызовет функцию afisareStudenti и передаст «событие». Итак, если вы измените:

 function afisareStudenti(){
   let i = 0; let bol = false;

к:

 function afisareStudenti(event){
   event.preventDefault()
   let i = 0; let bol = false;

Это правильно вызовет вашу функцию и предотвратит перезагрузку страницы действием «по умолчанию» этой кнопки отправки.

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

Can O' Spam 07.12.2022 17:36

@CanO'Spam Извините, я случайно нажал «Отправить», прежде чем написал остальную часть. Теперь мой ответ подходит? Я знаю, что это не влияет на конкретный вопрос, который возник у ОП, но это поможет им заставить свой код работать.

Datguy 07.12.2022 17:42

afisareMeniuAfisStudenti() — еще одна функция. Я разместил код, где у меня были проблемы. Эта часть кода работает просто отлично. И спасибо, я сделаю, как вы сказали. :)

AmicuLL 07.12.2022 17:47
Ответ принят как подходящий

Прокомментировав...

«У меня такое ощущение, что если бы аудитория получила более широкую картину, она могла бы принести гораздо больше пользы, поскольку OP можно было бы вернуть с более компактными / более чистыми и лучшими подходами к сопровождению».

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

Код, представленный в функции main кода примера, не только реализует использование создания узла на основе шаблона с помощью литералов шаблона и DOMParser.parseFromString , но также предотвращает поведение по умолчанию каждого ученика. кнопку отправки формы, используя делегирование событий.

function createStudentElement(studentId) {
  const markup =
    `<div class = "student-item" id = "AfisareStudenti${ studentId }">
      <h2> Afisare Student ${ studentId }</h2>
      <label>Ce student doriti sa modificati?&emsp;</label>
      <form>
        <label>Nume:</label><br>
        <input type = "text" id = "NumeStudent${ studentId }"><br>

        <label>Prenume:</label><br>
        <input type = "text" id = "PrenumeStudent${ studentId }"><br>

        <label>Data Nasterii:</label><br>
        <input type = "date" id = "intData${ studentId }"><br>

        <label>Foaie matricola:</label><br>
        <input type = "text" id = "FoaiaMatStud${ studentId }"><br><br>

        <input
          class = "butoane" type = "submit" value = "Afisare"
          onclick = "afisareMeniuAfisStudenti(${ studentId })"
        >
      </form>
    </div>`;

  const doc = (new DOMParser).parseFromString(markup, 'text/html');

  return doc.body.removeChild(doc.body.firstElementChild);
}

// the button click handler.
function afisareMeniuAfisStudenti(studentId) {
  console.info({ studentId })
}


function main() {
  const itemsRoot = document.querySelector('.student-items');

  // - prevent any form-submit by making use of event-delegation.
  itemsRoot.addEventListener('submit', evt => evt.preventDefault());

  // - just for demonstration purpose ...
  //   ... create student-items from a list of student IDs.
  [1, 2, 3, 4, 5].forEach(studentId =>
    itemsRoot.appendChild(
      createStudentElement(studentId)
    )
  );
}

main();
.as-console-wrapper { left: auto!important; width: 50%; min-height: 100%; }
<div class = "student-items"></div>

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