欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

JavaScript 如何获得粘贴的内容 ? 有大用

我想实现富文本编辑器那样的“纯文本模式粘贴”的功能,所以需要取出粘贴的内容,再加以处理。但是我不知道如何 取出这部分内容,请教一一下大家 。

真巧,前几天上线的知乎编辑器代码插件,有纯文本粘贴这个特性在里面。

JavaScript 是完全可以做到的!趁记忆未冷,总结一下:

W3C 标准下的做法(webkit/opera):

使用:

Clipboard API and events
clipboardData.getData('text/plain')

getData 方法接收一个 MIME 类型,比如你粘贴图片时可能是 image/png,粘贴富文本时可能是 text/html 和 text/plain 两种,支持的类型可以在 clipboardData.types 里面查询。

IE 下的做法:

IE 在这里其实很值得称赞,只是它支持的时候 W3C 标准还没有,所以只能用 Text 参数:

clipboardData.getData('Text')

在把选区内容替换成获取到的文本时,要注意两个问题:

CRLF

Windows 风格的换行是 \r,而其他系统是 \n,有两种方法获得处理一致的换行效果(以 Closure Library 为例):

* canonicalizeNewlines

canonicalizeNewlines = (str) -> str.replace(/(\r\n|\r|\n)/g, '\n')

* newLineToBr

newLineToBr = (str) -> str.replace(/(\r\n|\r|\n)/g, '<br>')

TextRange::pasteHTML

W3C 下可以用 Range::insertNode 获取插入对象的引用,但 IE 只能插入一个字符串,如果直接插入带换行的纯文本,这样换行就会丢失,因此实现了这样一个 hack(createHolder_ 函数辅助了这一过程):1)生成并插入一个占位元素 2)检索占位元素 3)替换占位元素为指定文本节点。

plugin.replaceTextIE = function(range, text) {
  this.createHolder_('i', function(holder, retrieve) {
    range.replaceContentsWithNode(holder)
    holder = retrieve()
    
    text = goog.string.canonicalizeNewlines(text)
    goog.dom.replaceNode(document.createTextNode(text), holder)
  })
}

Firefox 下的做法:

正常途径下获取不到剪贴板内容,需要实现一个 textFromHtml 函数。

代码插件是在 <code> 标签内部粘贴时去除格式,因此这样简单地处理就可以了:

code.textContent = textFromHtml(code.innerHTML)

如果要任意区域实现纯文本粘贴,我的建议是:

1)paste 事件发生之时,在选区起点之前和终点之后插入占位元素;

2)paste 之后(比如 setTimeout),获取两个占位元素中间的内容——即粘贴的内容;

3)转换粘贴的内容为纯文本;

附代码插件源码(

editor_plugin_code.js

)片断:

plugin.handlePaste_ = function(e) {
  var _ = this.getStateTuple(), state = _.state, range = _.range, code = _.code
  if (state !== Plugin.State.EDITABLE) return
  
  var text, textType = 'text/plain'
  var clipboard = e.getBrowserEvent().clipboardData
  if (clipboard) { // w3c(webkit,opera...)
    if (clipboard.types && goog.array.contains(clipboard.types, textType)) {
      e.preventDefault()
      text = clipboard.getData(textType)
      this.replaceText(range, text)
    }
  } else if (window.clipboardData) { // IE
    text = window.clipboardData.getData('Text')
    if (text) {
      e.preventDefault()
      this.replaceTextIE(range, text)
    }
  } else { // FF
    // TODO:rewrite
    var offset = range.getStartOffset()
    var selectedLength = range.getText().length
    var codeLength = function() {
      return code.firstChild ? goog.editor.node.getLength(code.firstChild) : 0
    }
    var endLength = codeLength() - offset - selectedLength
    setTimeout(function() {
      Plugin.cleanup(code)
      var caretOffset = codeLength() - endLength
      if (code.firstChild) {
        goog.dom.Range.createCaret(code.firstChild, Math.max(offset, caretOffset)).select()
      }
    })
  }
}

出于安全原因,现代的浏览器均已经禁止脚本缄默访问剪贴板,会需要用户授权。

单纯的 JavaScript 没有一个很完美的访问剪贴板(Clipboard)的方案。

和 jQuery 更是没有直接关系。

更多是采用 invisible Flash 技术来桥接粘贴功能。

推荐看下这个:

code.google.com/p/zeroc
var copyText = document.getElementById("myInput");
copyText.select();
document.execCommand("copy");
console.log(copyText.value);



来自  https://www.zhihu.com/question/20747877


普通分类: