You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
6.6 KiB
227 lines
6.6 KiB
<template>
|
|
<div>
|
|
<v-contextmenu ref="contextmenu" :disabled="disabled">
|
|
<v-contextmenu-item @click="addNote">{{$t('read.contextmenu.add')}}</v-contextmenu-item>
|
|
</v-contextmenu>
|
|
<el-tabs v-model="activeName" type="card" closable @tab-remove="removeTab">
|
|
<el-tab-pane :label="item.title" :name="item.title" v-for="(item,index) in openList" :key="item.title">
|
|
<el-row>
|
|
<el-col :span="18">
|
|
<div class="content" v-contextmenu:contextmenu :ref="'edit'+item.title" @mouseup="show" @contextmenu="selectText" v-html="item.content"/>
|
|
</el-col>
|
|
<el-col :span="5" class="ml3 note-list">
|
|
<el-row v-for="(item,index) in noteList" :key="index" class="mb2">
|
|
<el-tooltip class="item" effect="dark" :content="$t('read.tip.click_note_list')">
|
|
<el-card>
|
|
<div slot="header" class="clearfix">
|
|
<span>{{item.title}}</span>
|
|
<el-button style="float: right; padding: 3px 0" type="text">{{$t('button.del')}}</el-button>
|
|
</div>
|
|
<div class="text item choose-note" @click="jump(item)" @mouseover="highlighting(item)" @mouseout="reset(item)">
|
|
{{item.content}}
|
|
</div>
|
|
</el-card>
|
|
</el-tooltip>
|
|
</el-row>
|
|
</el-col>
|
|
</el-row>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
|
|
import Vue from 'vue'
|
|
|
|
export default Vue.extend({
|
|
name: 'read',
|
|
data(){
|
|
return {
|
|
//活动的论文标签
|
|
activeName:'',
|
|
//笔记列表
|
|
noteList:[],
|
|
//禁用右键菜单标志位
|
|
disabled:true,
|
|
//替换目标
|
|
replace:[]
|
|
}
|
|
},
|
|
computed:{
|
|
//打开的论文标签
|
|
openList(){
|
|
return this.$store.state.read.read
|
|
}
|
|
},
|
|
watch:{
|
|
//激活的论文标签
|
|
activeName(newVal){
|
|
this.$store.commit('read/choose',newVal)
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
//高亮笔记
|
|
highlighting(item:any){
|
|
let ele=document.getElementById(item.id)
|
|
if(ele&&this.GLOBAL.visible_in_container(this.$refs['edit'+this.activeName][0],ele)){
|
|
ele.classList.add('heightlight')
|
|
}
|
|
},
|
|
reset(item:any){
|
|
let ele=document.getElementById(item.id)
|
|
if(ele){
|
|
ele.classList.remove('heightlight')
|
|
}
|
|
},
|
|
//跳转到笔记位置
|
|
jump(item:any){
|
|
let ele=document.getElementById(item.id)
|
|
if(ele){
|
|
ele.scrollIntoView({
|
|
block:'center'
|
|
})
|
|
}
|
|
},
|
|
//是否显示右键菜单
|
|
show(){
|
|
let s=getSelection()
|
|
if(s){
|
|
this.disabled=s.isCollapsed
|
|
}else{
|
|
this.disabled=true
|
|
}
|
|
},
|
|
//关闭标签
|
|
removeTab(name:string){
|
|
this.$store.commit('read/close',name)
|
|
if(this.openList.length===0){
|
|
this.$router.push(this.localePath('/document'))
|
|
this.$store.commit('menus/none')
|
|
}
|
|
this.activeName=this.$store.state.read.activeName
|
|
},
|
|
//添加笔记
|
|
addNote(){
|
|
for(let index in this.replace){
|
|
if(this.replace[index].val&&this.replace[index].replaceVal){
|
|
this.replace[index].val.replaceWith(this.replace[index].replaceVal)
|
|
}
|
|
}
|
|
this.replace=[]
|
|
},
|
|
//显示选中文本
|
|
selectText(){
|
|
let selection = getSelection()
|
|
console.info(selection)
|
|
if(selection&&!this.disabled) {
|
|
let range = selection.getRangeAt(0)
|
|
console.info(range)
|
|
if (range.startContainer === range.endContainer) {
|
|
let tip = '不跨节点'
|
|
let anchorNode = range.startContainer
|
|
let bold = document.createElement('span')
|
|
bold.classList.add('bold')
|
|
if (range.endOffset - range.startOffset === anchorNode.length) {
|
|
console.info(tip + '全选')
|
|
bold.innerText = anchorNode.wholeText
|
|
this.replace.push({
|
|
val:anchorNode,
|
|
replaceVal: bold
|
|
})
|
|
} else {
|
|
console.info(tip + '选中一部分')
|
|
let start = document.createTextNode(anchorNode.substringData(0, range.startOffset))
|
|
let end = document.createTextNode(anchorNode.substringData(range.endOffset, anchorNode.length))
|
|
let span = document.createElement('span')
|
|
bold.innerText = anchorNode.substringData(range.startOffset, range.endOffset - range.startOffset)
|
|
span.append(start, bold, end)
|
|
this.replace.push({
|
|
val:anchorNode,
|
|
replaceVal: span
|
|
})
|
|
}
|
|
} else {
|
|
let tip = '跨节点'
|
|
let startNode = range.startContainer
|
|
let endNode = range.endContainer
|
|
console.info()
|
|
}
|
|
}else{
|
|
this.$message.error({
|
|
message:this.$t('read.tip.contextmenu_err').toString(),
|
|
showClose:true,
|
|
duration:1000
|
|
});
|
|
}
|
|
// let selectData=anchorNode.substringData(range.startOffset,range.endOffset-range.startOffset)
|
|
// console.info(selectData)
|
|
//
|
|
//
|
|
// let start=document.createTextNode(anchorNode.substringData(0,range.startOffset))
|
|
// console.info(start)
|
|
//
|
|
// let end=document.createTextNode(anchorNode.substringData(range.endOffset,anchorNode.length))
|
|
// console.info(end)
|
|
// let pre=selection.anchorNode.parentElement
|
|
// // pre.innerHTML=''
|
|
// let bold=document.createElement('span')
|
|
// bold.innerText=selectData
|
|
// bold.classList.add('bold')
|
|
// // pre.append(start,bold,end)
|
|
}
|
|
},
|
|
mounted() {
|
|
this.activeName=this.$store.state.read.activeName
|
|
for(let n=0;n<10;n++){
|
|
this.noteList.push({
|
|
id:`fuck${n}`,
|
|
title:`笔记${n}`,
|
|
content:`内容${n}`
|
|
})
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
<style>
|
|
.heightlight{
|
|
color: #74f2ff;
|
|
font-size: larger;
|
|
}
|
|
|
|
.choose-note{
|
|
cursor: pointer;
|
|
}
|
|
|
|
pre{
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.content{
|
|
height: 600px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.note-list{
|
|
height: 600px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.text {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.item {
|
|
margin-bottom: 18px;
|
|
}
|
|
|
|
.clearfix::before,
|
|
.clearfix::after {
|
|
display: table;
|
|
content: "";
|
|
}
|
|
.clearfix::after {
|
|
clear: both
|
|
}
|
|
</style>
|
|
|