需求实现:vue实现预览pdf文件,获取到鼠标选中的文字数据。调用pdf.js自带的搜索方法实现搜索功能(后期可以调用该接口满足其他的搜索需求)
1、下载pdf.js插件
地址: Getting Started
下载后解压文件放置在public文件夹下
2、在页面中引入
- //搜索框和搜索按钮
- <div style="margin-bottom:10px">
- <el-input prefix-icon="el-icon-search" v-model="selectText">el-input>
- <el-button type="primary" @click="sendMessage">搜索el-button>
- div>
使用的时候配合<iframe>一起使用,直接将标签的src属性指向pdf.js插件的 viewer.html页面,让该页面代为展示pdf即可
- //pdf展示模板
- <div class="iframe_box">
- <iframe width="100%" height="100%" :src="`/pdf/web/viewer.html?file=${pdfUrl}`" frameborder="0" id="myIframe">iframe>
- div>
使用的是本地pulic文件夹下的pdf文件
- data:{
- return{
- pdfUrl: "/2.pdf", //pdf地址
- selectText: "",//搜索框中的文本
- }
- }
3、获取选中文本,实现搜索
- mounted() {
- //这是滑选事件
- this.getSelectText();
- // 搜索时 接收数据
- this.getMessage()
- },
在mounted中执行事件,iframe页面加载完成就开始监听是否触发滑选事件,并将触发后的选中文本传给搜索框(iframe.contentWindow是iframe的window对象)
- // 滑选事件注册: 获取鼠标选中的文本
- getSelectText() {
- let _this = this;
- let iframe = document.getElementById('myIframe');
- let x = '';
- let y = '';
- let _x = '';
- let _y = '';
- // iframe 加载完成后执行并将双击事件过滤掉,因为双击事件可能也触发滑选,所以为了不误操作,将其剔除
- iframe.onload = function () {
- // 鼠标点击监听
- iframe.contentDocument.addEventListener('mousedown', function (e) {
- x = e.pageX;
- y = e.pageY;
- }, true);
- // 鼠标抬起监听
- iframe.contentDocument.addEventListener('mouseup', function (e) {
- _x = e.pageX;
- _y = e.pageY;
- if (x == _x && y == _y) return; //判断点击和抬起的位置,如果相同,则视为没有滑选,不支持双击选中
- var choose = iframe.contentWindow.getSelection().toString();
- _this.selectText = choose;
- }, true);
- };
- },
点击搜索按钮后像iframe发送数据,在mouted中接收数据。
- // 发送数据(搜索文字)
- sendMessage() {
- let vm = this;
- //获取iframe
- let iframe = document.getElementById('myIframe');
- //将滑选数据传入到iframe中
- iframe.contentWindow.postMessage(vm.selectText, '*');
- },
-
- // 接受数据
- getMessage() {
- //获取iframe
- let iframe = document.getElementById('myIframe');
- // iframe监听是否有数据传入,将传入的数据作为参数传递给pdf.js的find接口
- iframe.contentWindow.addEventListener('message', function (e) {
- //这里打印一下,看是否拿到了传入的数据
- console.log(e.data);
- // 这里打印的是pdf.js暴露出来的find接口
- console.log(iframe.contentWindow.PDFViewerApplication.findBar);
- // 输入查询数据
- iframe.contentWindow.PDFViewerApplication.findBar.findField.value = e.data;
- // 要求查询结果全体高亮
- iframe.contentWindow.PDFViewerApplication.findBar.highlightAll.checked = true;
- // 上面两部已经OK,触发highlightallchange方法。OK。全部完成,效果如文章开头,因为项目保密,所以就不这么着吧。
- iframe.contentWindow.PDFViewerApplication.findBar.dispatchEvent('highlightallchange');
-
- }, false);
-
- },
参考文章关于vue预览pdf的记录(vue-pdf,pdf.js,iframe标签)_Renyun_的博客-CSDN博客
需求实现:选中文字后,右击显示菜单打开弹窗,获取到选中的文字。单击鼠标时,菜单栏消失
1、使用vue-contextmenujs ,在methods中实现注册菜单和销毁菜单的方法
关于vue-contextmenujs 的使用 VUE右键菜单 vue-contextmenujs的使用_ZMJ_QQ的博客-CSDN博客
- //注册菜单
- onContextmenu(event) {
- event.preventDefault()
- this.$contextmenu({
- items: [
- {
- icon: "el-icon-circle-plus-outline",
- label: "添加标签",
- onClick: () => {
- this.addTagVisible = true;
- }
- },
- ],
- event,
- //菜单显示X坐标, 存在event则失效
- // x: event.clientX, //x轴坐标
- // y: event.clientY, //y轴坐标
- customClass: "class-a",
- zIndex: 3,
- minWidth: 100
- });
- return false;
- },
- //销毁菜单
- contextmenuDestory() {
- this.$contextmenu.destroy();
- },
2、改写iframe的加载方法,监听鼠标抬起时,将获取到选中文字赋值给弹窗中。在iframe中自定义鼠标右键事件。
因为我的菜单位置有问题,查找后发现vue-contextmenujs中,使用的是event.cilentX,该字段是只读的,可通过 Object.defineProperty。。重新设值,如果菜单位置正常则可忽略
注册完右键菜单后,如果不添加菜单销毁事件,则菜单栏会一直停留在页面上,需要在单击事件中销毁菜单。
- // 滑选事件注册: 获取鼠标选中的文本
- getSelectText() {
- let _this = this;
- let iframe = document.getElementById('myIframe');
- let x = '';
- let y = '';
- let _x = '';
- let _y = '';
- // iframe 加载完成后执行并将双击事件过滤掉,因为双击事件可能也触发滑选,所以为了不误操作,将其剔除
- iframe.onload = function () {
- // 鼠标点击监听
- iframe.contentDocument.addEventListener('mousedown', function (e) {
- x = e.pageX;
- y = e.pageY;
- }, true);
- // 鼠标抬起监听
- iframe.contentDocument.addEventListener('mouseup', function (e) {
- _x = e.pageX;
- _y = e.pageY;
- if (x == _x && y == _y) return; //判断点击和抬起的位置,如果相同,则视为没有滑选,不支持双击选中
- var choose = iframe.contentWindow.getSelection().toString();
- console.log(choose);
- _this.selectText = choose;
- //给弹窗中的字段辅助
- _this.tagform.tag = choose;
- }, true);
-
- // 自定义鼠标右键事件
- iframe.contentWindow.oncontextmenu = function (event) {
- if (_this.tagform.tag) {
- //重新设置菜单位置,如果菜单位置正常可忽略
- Object.defineProperty(event, 'clientX', {
- value: event.screenX,
- writable: true,
- configurable: true,
- enumerable: true,
- });
- //重新设置菜单位置,如果菜单位置正常可忽略
- Object.defineProperty(event, 'clientY', {
- value: event.screenY - 100,
- writable: true,
- configurable: true,
- enumerable: true,
- });
- // alert('请不要点击鼠标右键!');
- _this.onContextmenu(event)
- return false;//组织浏览器右键
- }
- };
- iframe.contentWindow.onclick = function () {
- _this.contextmenuDestory()
- }
-
- };
- },
参考文章:在iframe中获取选中的数据/iframe中鼠标事件_Flyfish2058的博客-CSDN博客_iframe 鼠标移动事件