<div id="expression" class="expression-content" ref="expression" contenteditable @blur="blurEdit" @input="change">
给自己记录用,能看懂的恰好功能相似的可借鉴下
输入框失去焦点时,获取到当前光标位置
blurEdit(e) {
const span = document.createElement('span');
// span.setAttribute('contenteditable', true);
const currentDom = window.getSelection().anchorNode;
if (!currentDom.previousElementSibling || (currentDom.previousElementSibling && currentDom.previousElementSibling.getAttribute('contenteditable') === 'false')) {
window.getSelection().anchorNode.before(span);
}
this.position = window.getSelection().getRangeAt(0);
},
变量点击时,存在业务代码
// 变量点击事件
nodeClick (data, type) {
if (data.children) {
return;
}
const span1 = document.createElement('span');
const span2 = document.createElement('span');
this.clickInsert(span1);
// 当选择函数时,默认带上()
if (type === 3) {
span1.innerText = ')';
span2.innerText = '(';
this.clickInsert(span2);
}
const span = document.createElement('span');
span.setAttribute('code', data.id);
span.setAttribute('contenteditable', false);
let color = '';
if (type === 2) {
color = '#980000';
} else if (type === 3) {
color = '#6aa84f';
} else {
color = '#027aff';
}
span.style.color = color;
span.innerText = data.label;
this.clickInsert(span);
this.setCursorPosition(span1);
},
// 设置指定光标位置
setCursorPosition (el) {
el.focus();
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
},
clickInsert(span) {
const div = document.getElementById('expression')
if(this.position === ''){
// 如果div没有光标,则在div内容末尾插入
div.focus()
const range = window.getSelection()
range.selectAllChildren(div)
range.collapseToEnd()
this.position = window.getSelection().getRangeAt(0)
}
// 插入光标位置
this.position.insertNode(span);
},
输入框change事件,加了之后,一直加加减减输入框内容时,会导致很多空span标签,不加一直加加减减输入框光标会消失,但不影响操作。(解决方案:可以删除掉多余的空span,后面有空再说)
change () {
// const currentDom = window.getSelection().anchorNode;
// const parentNode = currentDom.parentNode;
// if ((!currentDom.previousElementSibling || (currentDom.previousElementSibling && currentDom.previousElementSibling.getAttribute('contenteditable') === 'false'))
// || ((!parentNode.previousElementSibling || (parentNode.previousElementSibling && parentNode.previousElementSibling.getAttribute('contenteditable') === 'false')))) {
// this.position = window.getSelection().getRangeAt(0)
// const span = document.createElement('span');
// span.setAttribute('contenteditable', true);
// window.getSelection().anchorNode.before(span);
// }
},
扩展功能,如变量包含函数/方法,且前端需校验函数表达式正确性,处理加减乘除符号,最后再执行eval,先定义好变量及函数,在函数内判断函数传参类型、数量是否正确。
if (this.isFunction(this.customData.value)) {
try {
let res = this_.customData.value.replace(/([\+\-\*\/&]+)/g, function(match, $1) {
return `+"${$1}"+`;
});
res = res.replace(/'([^']+)'/g, function(match, $1) {
console.log(match)
return `'"${$1.replace(/\+"([\+\-\*\/])"\+/g, function (params, opera) {
return opera
})}"'`
})
this_.customData.value = eval(res);
} catch (error) {
this_.$message.warning('表达式公式错误');
return
}
}