纠错样式设置
// 纠错样式
.wordSignError {
margin: 0 5px;
display:inline-block;
vertical-align: middle;
animation:wordSignLight 3s ease infinite;
width:16px;
height:16px;
border:1px solid #ff0000;
border-radius:50%;
color:#ff0000;
font-size:13px;
line-height:14px;
cursor:pointer;
overflow:hidden;
letter-spacing: 10px !important;
padding-left:5px !important;
}
.wordSignError:before{content: "i ";}
.wordSignErrorButton {
position:fixed;
cursor:pointer;
z-index:999;
border:none;
box-shadow:none;
background:#14a56c;
width:80px;
height:24px;
border-radius:5px;
line-height:24px;
font-size:13px;
color:#fff;
text-align:center;
appearance:none;
display:none;
}
.wordSignErrorButton:focus{outline:none;}
.wordSignErrorEdit {
display:none;
position:fixed;
z-index:10001;
border:none;
box-shadow:none;
background:#e7f8f1;
width:300px;
height:330px;
border-radius:5px;
line-height:20px;
font-size:13px;
padding:15px 10px;
color:#333;
text-align:left;
appearance:none;
.cont{width:100%;margin:10px 0;
display:flex;
align-items:flex-start;
.tit{
height:40px;
font-size:15px;
line-height:40px;
text-align:right;
box-sizing: border-box;
padding-right:10px;
flex: 0 0 60px;
}
.con{
flex: 1 1 90%;
border:1px solid #ddd;
background:#fff;
height:115px;
overflow-y:auto;
font-size:14px;
line-height:20px;
color:#555;
padding:10px 10px;
box-sizing: border-box;
resize:none;
&:focus{outline:none;}
}
}
.close{
width:24px;
height:24px;
right:0px;left:0;
margin:auto;
top:5px;
cursor:pointer;
position:absolute;
&:before{
content:'';
displaY:block;
width:12px;
height:2px;
background:#333;
position:absolute;
left:0;right:0;top:0;bottom:0;
margin:auto;
transform:rotate(45deg);
}
&:after{
content:'';
displaY:block;
width:12px;
height:2px;
background:#333;
position:absolute;
left:0;right:0;top:0;bottom:0;
margin:auto;
transform:rotate(-45deg);
}
}
.butk{
text-align:center;
p{
display:inline-block;
height:34px;
line-height:34px;
width:75px;
background:#14a56c;
color:#fff;
cursor:pointer;
margin:0 10px;
border-radius:5px;
&:nth-child(2){
background:#ff0000;
}
}
}
}
.wordSignErrorEditClose{
position:absolute;
right:5px;
top:5px;
width:20px;
height:20px;
cursor:pointer;
}
@keyframes wordSignLight {
0%{transform:scale(1,1);box-shadow:0 0 3px 3px rgba(255,20,20,0.5);}
25%{transform:scale(1.2,1.2);box-shadow:0 0 1px 1px rgba(255,20,20,0.5);}
50%{transform:scale(1,1);box-shadow:0 0 3px 3px rgba(255,20,20,0.5);}
75%{transform:scale(1.2,1.2);box-shadow:0 0 1px 1px rgba(255,20,20,0.5);}
100%{transform:scale(1,1);box-shadow:0 0 3px 3px rgba(255,20,20,0.5);}
}
js 代码 部分
使用时 直接实例化,将绑定的element id传入即可
let editObj = new EditMark('content')
function EditMark (tid, show) {
// 有show则是展示,不能编辑
this.init(tid, show)
}
EditMark.prototype = {
clear() {
// 清除数据
let tedit = document.getElementById('wordSignErrorEdit')
if (tedit) {
let tedit1 = document.getElementById('wordSignErrorButton')
tedit.parentNode.removeChild(tedit)
if (tedit1) {
tedit1.parentNode.removeChild(tedit1)
}
window['clickEle'] = null
}
},
init (tid, show) {
this.clear()
let _this = this
this.focusEle = null
this.wWid = window.innerWidth
this.wHei = window.innerHeight
if (!show) {
let tbut = document.createElement('button')
tbut.setAttribute('id', 'wordSignErrorButton')
tbut.setAttribute('class', 'wordSignErrorButton')
tbut.innerHTML = '纠错'
document.body.append(tbut)
}
// 编辑框
let tp = document.createElement('div')
tp.setAttribute('class', 'wordSignErrorEdit')
tp.setAttribute('id', 'wordSignErrorEdit')
// 关闭
let tword = document.createElement('div')
tword.setAttribute('class', 'cont')
let twp = document.createElement('p')
twp.setAttribute('class', 'tit')
twp.innerHTML = '原文'
tword.append(twp)
let twc = document.createElement('p')
twc.setAttribute('class', 'con')
twc.setAttribute('id', 'backWord')
tword.append(twc)
let tword1 = document.createElement('div')
tword1.setAttribute('class', 'cont')
let twp1 = document.createElement('p')
twp1.setAttribute('class', 'tit')
twp1.innerHTML = '纠错'
tword1.append(twp1)
let twc1 = document.createElement('textarea')
if (show) { twc1.setAttribute('disabled', 'true') }
twc1.setAttribute('class', 'con')
twc1.setAttribute('maxlength', '500')
twc1.setAttribute('id', 'editWord')
tword1.append(twc1)
tp.append(tword)
tp.append(tword1)
// let twclose = document.createElement('p')
// twclose.setAttribute('class', 'close')
// twclose.addEventListener('click', function () {tp.style.display = 'none'})
// tp.append(twclose)
// 按钮
let tbutk = document.createElement('div')
tbutk.setAttribute('class', 'butk')
let tbutp = document.createElement('p')
tbutp.innerHTML = '确定'
let tbutp1 = document.createElement('p')
tbutp1.innerHTML = '取消纠错'
tbutp.addEventListener('click', function () {
tp.style.display = 'none'
let tw1 = document.getElementById('backWord')
let tw2 = document.getElementById('editWord')
// console.log(tw1, tw2)
let tele = document.getElementById(_this.focusEle)
tele.innerHTML = tw1.innerHTML + '|||||' + tw2.value
_this.focusEle = ''
})
tbutp1.addEventListener('click', function () {
tp.style.display = 'none'
let tele = document.getElementById(_this.focusEle)
tele.parentNode.removeChild(tele)
_this.focusEle = ''
})
tbutk.append(tbutp)
if (!show) {
tbutk.append(tbutp1)
}
tp.append(tbutk)
let tedit = document.getElementsByClassName('canEditWord')[0]
if (tedit) {
tedit.append(tp)
console.log(tedit)
} else {
document.body.append(tp)
}
window['clickEle'] = function (ele) {
var e = window.event || arguments.callee.caller.arguments[0]
_this.clickEle(ele, e)
}
document.getElementById(tid).addEventListener('mouseup', (e) => {
this.mouseUpd(e)
}, false)
},
mouseUpd (e) {
this.tselect = document.getSelection()
if (this.tselect.type === 'Range') {
// 有选择
this.tcount = this.tselect.getRangeAt(0)
// console.log(this.tcount)
this.tstr = this.tselect.toString()
if (this.tstr.indexOf('|||||') > -1) {
alert('此处已有纠错数据,无法重叠纠错')
return
}
if (this.focusEle) { return }
this.tedit = ''
this.createButton(e, 1)
} else {
let tbut = document.getElementById('wordSignErrorButton')
if (e.target !== tbut) {
tbut.style.display = 'none'
}
}
},
createButton (e, show) {
let tbut = document.getElementById('wordSignErrorButton')
if (!show) {
tbut.style.display = 'none'
return
}
if (!tbut) { return }
tbut.style.left = e.clientX - 80 + 'px'
tbut.style.top = e.clientY - 30 + 'px'
tbut.style.display = 'block'
tbut.onclick = null
tbut.onclick = () => {
this.tselect.removeRange(this.tcount)
tbut.style.display = 'none'
this.focusEle = this.insertIcon()
this.createEditDik(e, 1)
}
},
insertIcon () {
let ti = document.createElement('i')
ti.setAttribute('class', 'wordSignError')
ti.setAttribute('contenteditable', 'false')
let tid = 'id' + Date.now()
ti.setAttribute('id', tid)
ti.setAttribute('onclick', 'clickEle(this)')
this.tcount.insertNode(ti)
return tid
},
createEditDik (e, show) {
let tp = document.getElementById('wordSignErrorEdit')
if (!show) {
tp.style.display = 'none'
return
}
let tw1 = document.getElementById('backWord')
let tw2 = document.getElementById('editWord')
tw1.innerHTML = this.tstr
tw2.value = this.tedit || ''
tp.style.display = 'block'
let tleft = e.clientX + 15
let ttop = e.clientY + 15
if ((tleft + 300) > this.wWid) { tleft = tleft - 300 }
if ((ttop + 320) > this.wHei) { ttop = ttop - 320 }
tp.style.left = tleft + 'px'
tp.style.top = ttop + 'px'
},
clickEle(ele, e) {
if (this.focusEle) { return }
let tstr = ele.innerHTML
this.focusEle = ele.id
let tar = tstr.split('|||||')
this.tstr = tar[0]
this.tedit = tar[1]
this.createEditDik(e, 1)
}
}