一、VUE预览PDF文件并利用pdf.js获取鼠标选中的文字和搜索
需求实现: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博客
二、在iframe中注册鼠标右键菜单, 销毁菜单,获取iframe选中的文字
需求实现:选中文字后,右击显示菜单打开弹窗,获取到选中的文字。单击鼠标时,菜单栏消失
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 鼠标移动事件