【问题标题】:How to filter text content on copy/paste operation in a editable component (vue)如何在可编辑组件(vue)中的复制/粘贴操作中过滤文本内容
【发布时间】:2019-07-16 07:00:48
【问题描述】:

我已经实现了一个组件,该组件使用 contenteditable="true" 来获得在此 div 上编辑内容的可能性(如 textarea)。

从我的代码中关注一个 sn-p:

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)。

目前我在组件上使用带有 prop 的 v-html 属性,因为我需要在粘贴的文本上添加一个 html 自定义标签,但前提是用户单击按钮。

如何实现这种行为?

【问题讨论】:

  • 您可能想查看 Vue markdown,here's an example
  • 谢谢@jom,但是这个例子使用了一个库(marked.js)

标签: javascript vue.js vuejs2


【解决方案1】:

First 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,这似乎是我的问题的一个很好的起点。我不喜欢文本内容丢失回车,但我可以处理它。您可以建议我在安全内容可编辑中使用什么?清理条纹 html 标签是不够的?
  • @sergioska,您不会丢失回车符,只需将每个 \n 替换为 &lt;br/&gt; 即可
  • 您无法保护 contenteditable,但您应该通过过滤输入从后端保护它
  • 好的 @mooga 在那边我很安全,因为这个应用程序中没有后端 :)
【解决方案2】:

但我希望粘贴操作后只有文本版本(没有 html)。

您可以创建DOM元素或使用DOMParser()设置&lt;textarea&gt;value并获取该元素的.textContent

const textarea = document.querySelector("textarea");
let parser = new DOMParser();
let parsedHTML = parser.parseFromString(textarea.value, "text/html");
console.log(parsedHTML.body.textContent);
<textarea style="width:240px;height:50px;">
  <div>a<span>b</span><b>c</b></div>
</textarea>

【讨论】:

    猜你喜欢
    • 2019-04-18
    • 2019-01-16
    • 1970-01-01
    • 2020-07-22
    • 2015-09-08
    • 1970-01-01
    • 2023-02-09
    • 2015-07-02
    • 1970-01-01
    相关资源
    最近更新 更多