Отменить срабатывание onclick в динамически созданном элементе
Есть js-код и HTML-страница
function ChangeInput(object) {
let inputObj = document.getElementById("Email");
let parentDiv = document.getElementById("editBtn").parentNode;
inputObj.removeAttribute("disabled");
let saveObj = document.createElement("button");
saveObj.id = "saveObj";
saveObj.textContent = "Save";
saveObj.onclick = function() {
let parentDiv = document.getElementById("saveObj").parentNode;
let saveObj = document.getElementById("saveObj");
let editBtn = document.createElement("button");
let inputObj = document.getElementById("Email");
inputObj.addAttribute("disabled");
editBtn.id = "editBtn";
editBtn.textContent = "Edit";
editBtn.onclick = ChangeInput(this);
parentDiv.appendChild(editBtn);
saveObj.parentNode.removeChild(saveObj);
}
parentDiv.appendChild(saveObj);
object.parentNode.removeChild(object);
}
<form>
<div>
<input type="email" id="Email" placeholder="Email" value="[email protected]" disabled />
</div>
<div>
<button onclick="ChangeInput(this);" id="editBtn">Edit</button>
</div>
</form>
По клику на кнопке Edit создается кнопка Save. В элемент Save добавляется функция, которая должна вызываться по клику же, однако, в этом месте у меня и проблемы. Прошу указать на ошибки. DOM только начал изучать. JQuery не предлагать, пока DOM не освою - в JQuery не трогаю.
Ответы (1 шт):
- Метода addAttribute не существует. Есть
setAttribute - Ему нужно два параметра: setAttribute("disabled", "что-нибудь");
- cannot read property 'parentNode' of null". Это происходит при втором клике, когда на первом клике вы удаляете "editBtn", а на втором пытаетесь найти его.
- Интерпретатору всё равно, а человеческий глаз плохо воспринимает большой толстый столбик кода. Если не получается его как-то разбить на блоки/функции - можно хотя бы вставить пробельные строки между небольшими, логически связанными блоками кода.
Если так много используется getElementById, можно придумать коротенькую функцию, которая возвращает то же самое, но удобнее в использовании. Но если много увлекаться этим, через некоторое время можно обнаружить, что вы изобрели jQuery))
Ну а для исправления ошибки, нужен уже другой подход:
let isEditMode = false;
_id("btn").addEventListener("click", function() {
let input = _id("Email");
this.textContent = isEditMode ? "Edit" : "Save";
// «Тернарный оператор», Если isEditMode == true, возьмется "Edit", иначе - "Save";
input.disabled = isEditMode;
// Вместо setAttribute. Сразу указывается свойство - true/false.
isEditMode = !isEditMode;
// `!` - логическое "НЕ". Превращает false ←→ true и наоборот.
});
function _id(str) {
return document.getElementById(str);
}
<form onsubmit="return false;">
<div>
<input type="email" id="Email" placeholder="Email" value="[email protected]" disabled />
</div>
<div>
<button id="editBtn">Edit</button>
</div>
</form>
Помимо ряда других причин не использовать onclick в HTML... Если функция вызвана оттуда, консоль не может указывать на строчку ошибки. А вручную искать её в коде - трудно.
P.s. this.textContent = (input.disabled = (isEditMode = !isEditMode)) ? "Edit" : "Save"; "Умные" строчки кода тоже никому не нужны. Лучше несколько, но понятных строчек.