Атрибут hidden не работает в js коде
Пытался решить задачу по js, где надо написать код, который при клике на div превращался бы в textarea, где можно редактировать html код, а при расфокусировке отображал бы уже отредактированный вариант. Но столкнулся с со следующей проблемой, которую никак не могу понять.
Я хотел сделать через атрибут hidden, следующим образом:
let div = document.getElementById(`container`);
let textarea = document.createElement(`textarea`);
let divOuter = div.querySelector(`#userText`);
div.addEventListener(`click`, showTextarea);
function showTextarea() {
divOuter.hidden = true;
textarea.value = divOuter.outerHTML;
div.append(textarea);
textarea.focus();
};
div.addEventListener(`focusout`, closeTextarea);
function closeTextarea() {
divOuter.outerHTML = textarea.value;
console.log(divOuter.hidden)
divOuter.hidden = false;
console.log(divOuter.hidden)
textarea.hidden = true;
}
Почему-то при расфокусировке divOuter.hidden = false не срабатывает, div не появляется, хотя вторая консоль выводит false.
Почему divOuter.hidden = false не срабатывает по факту?
Но если добавить новую переменную с ссылкой на тот же div элемент вот так:
function closeTextarea() {
divOuter.outerHTML = textarea.value;
console.log(divOuter.hidden)
divOuter.hidden = false;
console.log(divOuter.hidden)
textarea.hidden = true;
let _divOuter = div.querySelector(`#userText`);
console.log(_divOuter.hidden)
_divOuter.hidden = false;
console.log(_divOuter.hidden)
};
То hidden в этом случае всё же сменяется в DOM и отображает div. Если честно, даже придумать не могу что-нибудь, почему это так работает.
HTML был следующим:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container">
<div id="userText">
<h1>Write here</h1>
<p>ok</p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Заранее благодарю за помощь.
Ответы (1 шт):
Основная проблема в использовании outerHTML.
Строчка
textarea.value = divOuter.outerHTML;
располагается ниже строчки
divOuter.hidden = true;
из-за этого этот атрибут есть в редактируемом тексте.
При обратной подстановке свойство меняется у исходного дива, и далее этот див полностью заменяется на то, что было внутри textarea, и, так как в значении не изменялся этот атрибут - он возвращается на место.
Вместо полной смены дива лучше использовать его innerHTML, тогда не нужно будет обновлять ссылку на него при каждом закрытии.
Например:
let div = document.getElementById(`container`);
let textarea = document.createElement(`textarea`);
let divOuter = div.querySelector(`#userText`);
let isEditing = false;
div.addEventListener(`click`, toggleTextarea);
function toggleTextarea() {
isEditing = !isEditing;
if (isEditing) {
showTextarea();
} else {
closeTextarea();
}
}
function showTextarea() {
textarea.value = divOuter.innerHTML;
divOuter.hidden = true;
textarea.hidden = false;
div.append(textarea);
textarea.focus();
};
textarea.addEventListener(`focusout`, closeTextarea);
textarea.addEventListener('click', e => e.stopPropagation());
function closeTextarea() {
divOuter.hidden = false;
textarea.hidden = true;
divOuter.innerHTML = textarea.value;
}
#container {
border: 1px solid red;
/* height: 100px;*/
}
#userText {
border: 1px solid green;
}
.ccc {
background-color: yellow;
}
<div id="container">
<div id="userText">
<h1>Write here</h1>
<p>ok</p>
</div>
</div>