JS处理剪贴板

JavaScript026

JS处理剪贴板,第1张

IE 是第一个支持剪贴板相关事件及通过 JavaScript 访问剪贴板数据的浏览器。IE 的实现成为了事实 标准,这是因为 Safari、Chrome、Opera 和 Firefox 都实现了相同的事件和剪贴板访问机制,后来 HTML5 也增加了剪贴板事件 。

(1) beforecopy:复制操作发生前触发。

(2) copy:复制操作发生时触发。

(3) beforecut:剪切操作发生前触发。

(4) cut:剪切操作发生时触发。

(5) beforepaste:粘贴操作发生前触发。

(6) paste:粘贴操作发生时触发。

这是一个比较新的控制剪贴板访问的标准,事件的行为及相关对象会因浏览器而异。在 Safari、 Chrome 和 Firefox 中,beforecopy、beforecut 和 beforepaste 事件只会在显示文本框的上下文菜 单(预期会发生剪贴板事件)时触发,但 IE 不仅在这种情况下触发,也会在 copy、cut 和 paste 事 件之前触发。无论是在上下文菜单中做出选择还是使用键盘快捷键,copy、cut 和 paste 事件在所有 浏览器中都会按预期触发。

通过 beforecopy、beforecut 和 beforepaste 事件可以在向剪贴板发送或从中检索数据前修改 数据。不过,取消这些事件并不会取消剪贴板操作。要阻止实际的剪贴板操作,必须取消 copy、cut 和 paste 事件。

剪贴板上的数据可以通过 window 对象(IE)或 event 对象(Firefox、Safari 和 Chrome)上的 clipboardData 对象来获取。在 Firefox、Safari 和 Chrome 中,为防止未经授权访问剪贴板,只能在剪 贴板事件期间访问 clipboardData 对象IE 则在任何时候都会暴露 clipboardData 对象。为了跨浏 览器兼容,最好只在剪贴板事件期间使用这个对象。

clipboardData 对象上有 3 个方法:getData()、setData()和 clearData(),其中 getData() 方法从剪贴板检索字符串数据,并接收一个参数,该参数是要检索的数据的格式。IE 为此规定了两个选 项:"text"和"URL"。Firefox、Safari 和 Chrome 则期待 MIME 类型,不过会将"text"视为等价于 "text/plain"。

setData()方法也类似,其第一个参数用于指定数据类型,第二个参数是要放到剪贴板上的文本。 同样,IE 支持"text"和"URL",Safari 和 Chrome 则期待 MIME 类型。不过,与 getData()不同的是, Safari 和 Chrome 不认可"text"类型。只有在 IE8 及更早版本中调用 setData()才有效,其他浏览器会 忽略对这个方法的调用。

这里的 getClipboardText()函数相对简单,它只需要知道 clipboardData 对象在哪里,然后 便可以通过"text"类型调用 getData()。相应的,setClipboardText()函数则要复杂一些。在确定 clipboardData 对象的位置之后,需要根据实现以相应的类型(Firefox、Safari 和 Chrome 是 "text/plain",而 IE 是"text")调用 setData()。

如果文本框期待某些字符或某种格式的文本,那么从剪贴板中读取文本是有帮助的。比如,如果文 本框只允许输入数字,那么就必须检查粘贴过来的值,确保其中只包含数字。在 paste 事件中,可以 确定剪贴板上的文本是否无效,如果无效就取消默认行为,如下面的例子所示:

这个 onpaste 事件处理程序确保只有数字才能粘贴到文本框中。如果剪贴板中的值不符合指定模 式,则取消粘贴操作。Firefox、Safari 和 Chrome 只允许在 onpaste 事件处理程序中访问 getData() 方法。

因为不是所有浏览器都支持剪贴板访问,所以有时候更容易屏蔽一个或多个剪贴板操作。在支持 copy、cut 和 paste 事件的浏览器(IE、Safari、Chrome 和 Firefox)中,很容易阻止事件的默认行为。 在 Opera 中,则需要屏蔽导致相应事件的按键,同时阻止显示相应的上下文菜单。

  很酷吧,相信经常在网上复制粘贴的人应该不陌生,我也是经历过,觉得很神奇,所以就寻思着是不是也在自己的博客里面也实现这个功能,经过一番查资料于研究,我总算弄明白了其中的原委,并实际应用于我的博客,你可以复制我粘贴试试,觉得酷的话就可以往下接着看了!下面来看一下实现过程。这里说明一下,浏览器版本较低的话可能`addEventListener()`不支持,特别是IE浏览器,IE8以前包括IE8的版本都不支持此方法。

    当用户选中某段内容时window.getSelection()获取一个Selection对象,将这个`objSelection.tostring()`,就是选中区的内容,这里可以用` var selectionString = window.getSelection().toString()`在控制台查看,能在控制台查看说明我们就可以通过js获取到,selectionString + '自定义内容',到这里复制的原内容我们就有了。这里我们要创建一个DOM容器来存`objSelection.tostring()`,最好是可以换行的,如p、div、textarea等。

  当一个HTML文档切换到设计模式时,document暴露 execCommand 方法,该方法允许运行命令来操纵可编辑内容区域的元素,这里主要用其中的copy命令来实现复制功能,听说插件Clipboard.js也是调用这个方法实现复制功能的`bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)`,第一个参数是命令的名称,字符串类型,后两个参数我们可以不用,返回bool值,如果是 false则表示操作不被支持或未被启用命令只介绍用到的copy命令:

  >copy:拷贝当前选中内容到剪贴板。启用这个功能的条件因浏览器不同而不同,而且不同时期,其启用条件也不尽相同。使用之前请检查浏览器兼容表,以确定是否可用。

  这是很重要的一步,这是复制内容的关键命令。这里我们只需要在正确的时间执行`document.execCommand('copy')`即可。

  addEventListener()方法用于向指定元素添加事件句柄,这里我就抛开文档,就针对本次功能对这个HTML DOM方法进行通俗的解释了,这里主要用来规定我们自定义复制功能的有效DOM范围,来个例子:

  //body中有<div id="test">content</div>

  var el = document.getElementById('test')

  el.addEventListener('copy', function (e){

    // 触发copy事件后的处理

  }

  这个例子中我们实现的功能将只在id为test的DOM元素里有效,其它地方将恢复默认复制功能。

    Range表示包含节点和部分文本节点的文档片段。用`var range = document.createRange()`方法创建,这里面为什么要创建Range呢,主要是用来存储Selection对象的开始位置和终点位置,因为我们是要阻止默认的copy事件,让copy的内容是用户选中的内容加上我们自定义的内容,再将这个内容放入粘贴板,形成最终的粘贴内容。`document.createRange`得到是还没有放内容的片段,我们我们还会用到`Range.setStart()`设置Range的起点和`Range.setEnd()`设置Range的终点。最终`selectionObj.removeAllRanges()`将selectionObj中的默认Range 去掉,`selectionObj.addRange(range)`,粘贴板就有了,不出意外去粘贴就会有选中的内容加自定义的内容了。

源码可以联系作者。这里有个特别注意的点,如果是原生js的话直接调用函数就可以,如果是vuejs的话图片中可以看到,我是在mounted()钩子函数里调用,而不是在created()钩子函数里调用,这里一定不能在created()钩子函数里调用,为什么呢?

因为created()执行的时候一般是在html渲染前的操作,此时el还是undefined,所以执行getElementById()就会报错,created()适合做html渲染前的数据初始化工作。而mounted()一般是在html渲染完成后的操作,此时el,data都已经加载完成,一般对dom的操作都写在mounted中,这是个要注意的点,喜欢的话就给作者点个心,谢谢