Я реализовал компонент, который использует contenteditable="true", чтобы получить возможность редактирования содержимого в этом div (например, текстовое поле).
Следуйте фрагменту из моего кода:
export default {
name: 'divArea',
props: ['value'],
mounted() {
this.$el.innerHTML = this.value;
},
methods: {
updateHTML(e) {
const html = e.target.innerHTML;
this.$emit('input', html);
},
},
}<template>
<div contenteditable = "true"
v-once
v-html = "value"
@input = "updateHTML"
@paste = "onPaste"
class = "txtArea"></div>
</template>Я пытаюсь реализовать функцию вставки в этой области, чтобы скопировать блок контента с html-страницы, но я хотел бы иметь только текстовую версию после операции вставки (без html).
В настоящее время я использую атрибут v-html с поддержкой моего компонента, потому что мне нужно добавить пользовательский тег html во вставленный текст, но только если пользователь нажимает кнопку.
Как я могу реализовать это поведение?
Спасибо @jom, но в этом примере используется библиотека (marked.js)



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


but I would like to have only text version after paste operation (no html).
Вы можете создать элемент DOM или использовать DOMParser(), чтобы установить value элемента <textarea> и получить .textContent элемента.
const textarea = document.querySelector("textarea");
let parser = new DOMParser();
let parsedHTML = parser.parseFromString(textarea.value, "text/html");
console.info(parsedHTML.body.textContent);<textarea style = "width:240px;height:50px;">
<div>a<span>b</span><b>c</b></div>
</textarea>Во-первых contenteditable это настоящий Дьявол и я рекомендую не использовать его, но в любом случае это было мое решение
let contenteditable = document.querySelector('[contenteditable]')
contenteditable.addEventListener('paste', function(e){
// Prevent the default pasting event and stop bubbling
e.preventDefault()
e.stopPropagation()
// Get the clipboard data
let paste = (e.clipboardData || window.clipboardData).getData('text/plain')
// Do something with paste like remove non-UTF-8 characters
paste = paste.replace(/\x0D/gi, "\n")
e.target.textContent += paste
})
вторая часть, если вы хотите добавить пасту, где был cursor
instead of
e.target.textContent += paste
вы можете использовать Selection()
// Find the cursor location or highlighted area
const selection = window.getSelection()
// Cancel the paste operation if the cursor or highlighted area isn't found
// if (!selection.rangeCount) return false
// Paste the modified clipboard content where it was intended to go
if (selection.getRangeAt(0).collapsed){
// TextareaManager.AddToCursor(document.createTextNode(paste))
if (selection.getRangeAt(0).endContainer.nodeName != "DIV"){
selection.getRangeAt(0).insertNode(document.createTextNode(paste))
}else {
e.target.childNodes[0].textContent += paste
}
selection.getRangeAt(0).collapse(false)
}else {
e.target.appendChild(document.createTextNode(paste))
}
Спасибо @mooga, кажется, это отличная отправная точка для моей проблемы. Мне не нравится, что текстовый контент потерял возврат каретки, но я могу над этим поработать. Что вы можете предложить мне использовать в безопасности contenteditable? санировать, что полосатых html-тегов недостаточно?
@sergioska, вы не теряете возврат каретки, просто замените каждый \n на <br/> вместо этого
вы не можете защитить contenteditable, но что вы должны сделать, чтобы защитить его с внутренней стороны, отфильтровав входные данные
Хорошо, @mooga, с этой стороны я в безопасности, потому что в этом приложении нет серверной части :)
Возможно, вы захотите изучить уценку Vue, вот пример.