Работает ли getElementById с элементами, созданными с помощью javascript?

Я создал две функции для загрузки расширенных представлений за месяц в разделе архива моего блога при нажатии ссылки:

// Load open view of a month in the Archive section
function loadMonth(date) {
  // Remove other open month
     removeMonth();

  // Hide opening month's link
  // Define variable to hold month anchor tag
     var monthLink = document.getElementById(date); 
     monthLink.style.display = "none"; // Hide month anchor

  // Define new open month node and its attributes
     var openMonth = document.createElement("div");
     openMonth.setAttribute("id", "openMonth");
     openMonth.innerHTML = "Testing one, two, three.";

  // Insert open month
  // Define a variable to hold the archive Div node
     var archive = document.getElementById("archive");
  // Insert the open month in the archive node before it's link
     archive.insertBefore(openMonth,monthLink);

     return;
  }


// Close full view of a month and replace with respective link
function removeMonth() {

  // Define global function vars
     var archive = document.getElementById("archive"); // Define a var to hold the archive Div node
     var openMonth = document.getElementById("openMonth"); // Define var to hold the open month Div node

  // Get date of full view month for replacement anchor tag where ID = date
     var month = openMonth.getElementsByTagName("span")[0].innerHTML; // Define var to hold the name of the open month
     var date = (new Date(month + " 15, 2008").getMonth() + 1); // Define var to hold the numerical equivalent of the month
     var year = archive.getElementsByTagName("h3")[0].innerHTML.split(" "); // Define var to hold the year being displayed in the archive
     date = year[1] + "" + date; // Change date var to string and insert year

  // Remove the open month
     archive.removeChild(openMonth);

  // Show Link for that month
     document.getElementById(date).className = "big"; // Fixes display error when anchor has class firstLink
     document.getElementById(date).style.display = "inline"; // Returns link from display "none" state
     return;
}

Функции работают при запуске с исходным статическим содержимым, но при нажатии второй ссылки в архиве они ничего не делают. Мне интересно, может быть, потому, что элементы, созданные моими функциями, не могут быть вызваны document.getElementById. Возможно, следует использовать другой метод доступа к этим узлам или, может быть, заменить «документ» чем-то, что также работает с элементами, созданными с помощью javascript?

Любой совет будет очень признателен. Спасибо.

Можете ли вы опубликовать где-нибудь рабочий пример вашего кода (например, тот, который показывает проблему) (например, здесь pastebin.me)? Глядя на ваш код, я считаю, что в вашем подходе есть общее заблуждение.

Tomalak 05.12.2008 19:53
Поведение ключевого слова "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) для оценки ваших знаний,...
5
1
8 035
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вас должно устроить:

openMonth.id = "openMonth";

getElementById() может работать только в том случае, если элемент является частью DOM, но, поскольку вы уже используете insertBefore(), это всего лишь примечание.

Здесь есть общий источник путаницы: атрибут названный «id» не обязательно является тем, который является определенный в качестве идентификатора элемента в базовом DTD. В декларативном HTML они связываются автоматически. Когда вы используете setAttribute(), вы не более чем создаете атрибут названный «id». Сам идентификатор элемента доступен через свойство .id.

Редактировать

Для меня работает следующее:

function test()
{
  // create element, set ID
  var p = document.createElement("P");
  p.innerHTML = "Look ma, this is a new paragraph!";
  p.id = "newParagraph";

  // make element part of the DOM
  document.getElementsByTagName("BODY")[0].appendChild(p);

  // get element by ID
  var test = document.getElementById("newParagraph");
  alert(test.innerHTML);
}

К сожалению, изменение этой строки не устранило проблему. Не уверен, что вы имели в виду под "getElementById (), может работать только в том случае, если элемент является частью DOM ..." Разве объект, который я вставляю, не является частью DOM? Или поэтому вы сказали, что это всего лишь примечание ...

bloudermilk 05.12.2008 11:19

Сразу после того, как вы создали элемент, он просто там, ни к чему не подключен и невидимый для getElementById (). Вы должны добавить его в DOM, чтобы сделать его видимым. Добавлю тестовый пример.

Tomalak 05.12.2008 11:46

Поскольку вы добавляете элемент «openMonth» в элемент «архив» с помощью insertBefore (), где-то должна быть дополнительная ошибка. Может быть, сам элемент архива не является частью документа?

Tomalak 05.12.2008 12:06
Ответ принят как подходящий

Чтобы ответить на ваш главный вопрос: document.getElementByIdделает работает с динамически добавляемыми элементами.

В вашем примере кода вы создаете div openMonth и устанавливаете его innerHTML. Затем в теге удаления вы делаете это:

var month = openMonth.getElementsByTagName("span")[0].innerHTML;

openMonth.getElementsByTagName("span") не будет существовать и получит сообщение об ошибке, потому что нет элементов диапазона. Я не знаю, ошибка ли это в коде или это просто неполный образец в сообщении.

Ты совершенно прав! Честно говоря, я не продвинулся так далеко в своем коде. Я новичок в Javascript и не понимал, что это сбрасывает всю функцию. Большое спасибо!

bloudermilk 05.12.2008 11:25

Другая идея - вы повторно используете идентификатор openMonth для разных элементов, возможно, это проблема, даже если вы сначала удалите предыдущий элемент.

Вы можете попробовать использовать класс вместо id или сохранить глобальную переменную с «элементом текущего месяца».

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

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

Надеюсь, что это помогло

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