Я создал две функции для загрузки расширенных представлений за месяц в разделе архива моего блога при нажатии ссылки:
// 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?
Любой совет будет очень признателен. Спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вас должно устроить:
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? Или поэтому вы сказали, что это всего лишь примечание ...
Сразу после того, как вы создали элемент, он просто там, ни к чему не подключен и невидимый для getElementById (). Вы должны добавить его в DOM, чтобы сделать его видимым. Добавлю тестовый пример.
Поскольку вы добавляете элемент «openMonth» в элемент «архив» с помощью insertBefore (), где-то должна быть дополнительная ошибка. Может быть, сам элемент архива не является частью документа?
Чтобы ответить на ваш главный вопрос: document.getElementByIdделает работает с динамически добавляемыми элементами.
В вашем примере кода вы создаете div openMonth и устанавливаете его innerHTML. Затем в теге удаления вы делаете это:
var month = openMonth.getElementsByTagName("span")[0].innerHTML;
openMonth.getElementsByTagName("span") не будет существовать и получит сообщение об ошибке, потому что нет элементов диапазона. Я не знаю, ошибка ли это в коде или это просто неполный образец в сообщении.
Ты совершенно прав! Честно говоря, я не продвинулся так далеко в своем коде. Я новичок в Javascript и не понимал, что это сбрасывает всю функцию. Большое спасибо!
Другая идея - вы повторно используете идентификатор openMonth для разных элементов, возможно, это проблема, даже если вы сначала удалите предыдущий элемент.
Вы можете попробовать использовать класс вместо id или сохранить глобальную переменную с «элементом текущего месяца».
Это работает, только если вы укажете идентификатор для элемента при его создании. Я помню, что когда я создавал элементы на лету, я устанавливал счетчик для идентификатора или, если данные извлекались из базы данных, я использовал бы вместо этого идентификатор строки.
Я бы создал элемент, используя поле innerHTML элемента и вставив элемент в виде текста, тогда движок рендеринга взял бы его оттуда. Это не лучший способ сделать это, но он очень быстрый. Я очень тороплюсь ...
Надеюсь, что это помогло
Можете ли вы опубликовать где-нибудь рабочий пример вашего кода (например, тот, который показывает проблему) (например, здесь pastebin.me)? Глядя на ваш код, я считаю, что в вашем подходе есть общее заблуждение.