#javascript #html
#javascript #HTML
Вопрос:
Вот в чем дело:
Редактируемые содержимое плохие. Firefox обрабатывает это чем-то вроде div1
и Chrome делает это так div2
.
Оба имеют одинаковое текстовое содержимое (с точки зрения пользователя), но они структурированы по-разному.
Когда я получаю оба текстовых содержимого с помощью innerText
, я получаю разные результаты из-за того, как они структурированы.
Есть ли способ получить эти тексты и вернуть ту же строку (поскольку они выводят точно такой же текст на экран)?
Что-то вроде:
div1 = div2 = "Line1nLine2nnLine3nnnLine4"
(фактически, это div1
результат, поскольку он состоит только из текста и разрывов). div2
в этом случае проблема.
Псевдокод того, что мне нужно:
«Получите мое текстовое содержимое этих файлов div
с количеством разрывов на основе того, что отображается на экране».
Конечная цель:
Чтобы последовательно вставлять новый текст в обе структуры, мне нужен способ обрабатывать их одинаково.
const div1 = document.getElementById('div1');
const div2 = document.getElementById('div2');
const p1 = document.getElementById('p1');
const p2 = document.getElementById('p2');
p1.innerText = JSON.stringify(div1.innerText);
p2.innerText = JSON.stringify(div2.innerText);
#div1 {
border: 1px dotted blue;
}
#div2 {
margin-top: 40px;
border: 1px dotted red;
}
<div id="div1" contenteditable>
Line1
<br>
Line2
<br>
<br>
Line3
<br>
<br>
<br>
Line4
</div>
<p><b>Div1 innerText:</b></p>
<p id="p1"></p>
<div id="div2" contenteditable>
<div>Line1</div>
<div>Line2</div>
<div><br></div>
<div>Line3</div>
<div><br></div>
<div><br></div>
<div>Line4</div>
</div>
<p><b>Div2 innerText:</b></p>
<p id="p2"></p>
Комментарии:
1. Любое закрытие
</div>
добавитn
, а также любой<br>
2. Почему бы вам не использовать
<textarea>
вместоcontenteditable
?3. @iArcadia Мне нужно оформить некоторые части содержимого в системе «отмеченных упоминаний пользователей».
4. Все еще возможно. Вы могли бы преобразовать свой
<div>
контент в<textarea>
по щелчку мыши, а затем изменить его при нажатии снаружи. Просто идея.5. @iArcadia как я могу преобразовать
div
содержимое a вtextarea
?div
Было быcontenteditable
ли это? У вас есть какой-нибудь пример кода для этого? Спасибо!
Ответ №1:
Я предложил вам в комментариях преобразовать ваш <div>
контент в <textarea>
элемент. Это решение позволяет избежать различий в поведении между Firefox и Chrome.
Ниже приведен простой пример того, как этого можно достичь. Я думаю, вы сможете адаптировать его к тому, что именно вы хотите (например, переключившись <p>
на <div>
).
const contentEditable = document.querySelector('#content-editable'),
htmlPreview = document.querySelector('#html-preview');
htmlPreview.innerText = contentEditable.innerHTML;
contentEditable.addEventListener('click', contentEditableHtmlToTextarea);
/**
* Converts HTML of #content-editable into <textarea>.
*/
function contentEditableHtmlToTextarea() {
const textarea = document.createElement('textarea'),
height = contentEditable.offsetHeight;
// Converts <p> tags to rn.
textarea.value = this.innerHTML
.replace(/^s*/gm, '')
.replace(/<p>(.*?)</p>/g, '$1rn')
.trim();
// Updates #content-editable HTML.
this.innerHTML = '';
this.appendChild(textarea);
textarea.style.height = `${height}px`;
htmlPreview.style.display = 'none';
this.removeEventListener('click', contentEditableHtmlToTextarea);
// A bit tricky, but without timeout, the callback is directly called.
setTimeout(() => {
document.addEventListener('click', contentEditableTextareaToHtml);
}, 0);
}
/**
* Converts <textarea>'s value into HTML for #content-editable.
*/
function contentEditableTextareaToHtml(e) {
const textarea = contentEditable.querySelector('textarea'),
// Converts lines into <p> tags.
html = textarea.value.replace(/^(. ?)$/gm, '<p>$1</p>');
// Checks if the mouse click is outside the <textarea>.
if (e.target !== textarea) {
// Updates #content-editable HTML.
textarea.remove();
contentEditable.innerHTML = html;
htmlPreview.innerText = contentEditable.innerHTML;
htmlPreview.style.display = 'block';
document.removeEventListener('click', contentEditableTextareaToHtml);
contentEditable.addEventListener('click', contentEditableHtmlToTextarea);
}
}
div {
padding: 3px;
border: 1px solid #000;
}
textarea {
margin: 0 auto;
display: block;
width: 98%;
}
<div id="content-editable">
<p>Line 1</p>
<p>Line 2</p>
<p>Line 3</p>
</div>
<pre id="html-preview"></pre>