【vue】可编辑div部分字段高亮

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011250535/article/details/80572799

【vue】可编辑div部分字段高亮

参考了帖子:https://segmentfault.com/a/1190000008261449

以及帖子:https://blog.csdn.net/smartsmile2012/article/details/53642082

这次的组件:
1.通用性不强,是为了特殊功能而制定的,放在这里是为了方便日后查阅内部的相关知识点;

2.实现的是输入类似(1and2or3)or(4and5)这样的逻辑运算表达式的时候,高亮and or单词,加粗左括号(右括号)

3.另外,代码有缺陷:a.输入法中文输入的时候会错乱,重复输入值;b.不能阻止输入其他字符

4.由于其中有一部分是借鉴的代码,所以IE9的部分没测试;多半是不行的,项目也不需支持IE9

template 代码
<template>
    <div class="edit-div"
         v-html="innerText"
         :contenteditable="canEdit"
         @focus="isLocked = true"
         @blur="isLocked = false"
         @input="changeText">
    </div>
</template>
script 代码
<script type="text/ecmascript-6">
    export default{
      name: 'edit-div',
      props: {
        value: {
          type: String,
          default: ''
        },
        canEdit: {
          type: Boolean,
          default: true
        }
      },
      data() {
        return {
          isLocked: false,
          tempText: this.value
        }
      },
      computed: {
        innerText: {
          get() {
            return this.initText(this.value)
          },
          set() {}
        }
      },
      methods: {
        initText(value) {
          return value.replace(/(\s*and\s*)/g, `<span class="red">and</span>`).replace(/(\s*or\s*)/g, `<span class="red">or</span>`).replace(/(\s*\(\s*)/g, `<span style="font-weight: 700;">(</span>`).replace(/(\s*\)\s*)/g, `<span style="font-weight: 700;">)</span>`)
        },
        changeText(event, value) { // value为新值
          this.$el.focus()
          let html = null
          let ifChangedByValue = false
          // 自动高亮and or ( ) 的html
          if (value) {
            ifChangedByValue = true
          } else {
            value = this.$el.innerText
          }
          html = value.replace(/(\s*and\s*)/g, `<span class="red">and</span>`).replace(/(\s*or\s*)/g, `<span class="red">or</span>`).replace(/(\s*\(\s*)/g, `<span style="font-weight: 700;">(</span>`).replace(/(\s*\)\s*)/g, `<span style="font-weight: 700;">)</span>`)
          let offsetInit = value ? value.length : 0 // 当前编辑的节点的偏移值,初始化为总长度或0
          const newValueList = value.split('')
          const oldValueList = this.tempText.split('')
          if (newValueList.length > oldValueList.length) { // 输入值
            for (const indexOfValue in newValueList) {
              if (newValueList[indexOfValue] !== oldValueList[indexOfValue]) {
                offsetInit = parseInt(indexOfValue) + 1
                break
              }
            }
          } else { // 删除值
            for (const indexOfValue in oldValueList) {
              if (newValueList[indexOfValue] !== oldValueList[indexOfValue]) {
                offsetInit = parseInt(indexOfValue)
                break
              }
            }
          }
          if (window.getSelection) {
            // IE9 and non-IE
            const sel = window.getSelection()
            if (sel.getRangeAt && sel.rangeCount) {
              let range = sel.getRangeAt(0)
              range.deleteContents()
              var el = document.createElement('div')
              el.innerHTML = html
              var frag = document.createDocumentFragment()
              var node
              const nodeList = []
              while ((node = el.firstChild)) {
                nodeList.push(frag.appendChild(node))
              }
              this.$el.innerHTML = '' // 清空原有的html
              range.insertNode(frag)
              let offsetTemp = 0
              let nodeIndex = 0
              for (const indexOfNodes in this.$el.childNodes) {
                let currentNodeLength = 0
                let nodeType = 1
                if (this.$el.childNodes[indexOfNodes].nodeType === 1) { // span节点
                  currentNodeLength = this.$el.childNodes[indexOfNodes].innerText.length
                  nodeType = 1
                } else if (this.$el.childNodes[indexOfNodes].nodeType === 3) { // text节点
                  currentNodeLength = this.$el.childNodes[indexOfNodes].nodeValue.length
                  nodeType = 3
                }
                if (offsetTemp + currentNodeLength >= offsetInit) {
                  if (nodeType === 1) { // 编辑的节点的偏移值计算
                    offsetInit = 1 // 元素节点偏移值固定为0、1
                  } else {
                    offsetInit = offsetInit - offsetTemp // 文本节点偏移值计算
                  }
                  nodeIndex = parseInt(indexOfNodes)
                  break
                }
                offsetTemp += currentNodeLength // 累加编辑的节点之前的节点的长度
              }
              if (nodeList && nodeList[nodeIndex]) { // nodeList[nodeIndex]为编辑的时候所在的节点
                range = range.cloneRange()
                range.setStart(nodeList[nodeIndex], offsetInit)
                range.collapse(true)
                sel.removeAllRanges()
                sel.addRange(range)
              }
            }
          } else if (document.selection && document.selection.type !== 'Control') {
            // IE < 9
            document.selection.createRange().pasteHTML(html)
          }
          this.tempText = this.$el.innerText
          if (!ifChangedByValue) { // 如果是通过父组件传值改变值,则不再通知父组件;否则$emit
            this.$emit('input', this.$el.innerText) // 通知父组件,value值改变
          }
        }
      }
    }
</script>


css代码
.edit-div {
        width: 100%;
        height: 100%;
        overflow: auto;
        word-break: break-all;
        outline: none;
        user-select: text;
        white-space: pre-wrap;
        text-align: left;
        .red {
          font-weight: 700;color:red;letter-spacing: 0;
        }
        &[contenteditable=true]{
            user-modify: read-write-plaintext-only;
            &:empty:before {
                content: attr(placeholder);
                display: block;
                color: #ccc;
            }
        }
    }
展开阅读全文

高亮部分怎么了?

02-17

#include rn#include rn#include rnrnusing namespace std;rnrnvoid main(void)rn rn string line,sentence, sentence_append;rn ifstream infilestream("data.txt"); //File object.rn char end_of_sentence[3]='.','?','!'; //End Mark.rn int position_end=0, position_start=0; // The position which could copy to the sentence.rn int sentence_size=0, append_mark; //If it needs append, append=1;rn bool appendmark=0;rnrn //cout<<"Please input a file name"<>filename;rnrnrnrnrn while (!infilestream.eof())rn getline(infilestream,line);rn position_end=0;rn position_start=0;rn string sentence_append;rnrn dorn position_end=line.find_first_of(end_of_sentence, position_start);rnrn //Count the size of sentencern if(position_start==0 && position_end!=string::npos)rn sentence_size=position_end;rnrn else if (position_start!=0 && position_end!=string::npos)rn sentence_size=position_end-position_start;rn rn else if(position_start!=0 && position_end==string::npos)rn sentence_size=line.length()-position_start;rnrn else rn sentence_size=line.length();rnrnrn //Create the sentencern if(position_end!=string::npos && appendmark==false)rnrn [color=#FF0000]line.copy(sentence,sentence_size, position_start);[/color]rn rn rn else if(position_end==string::npos && appendmark==false)rn [color=#FF0000]line.copy(sentence,sentence_size, position_start);[/color]rn appendmark=true;rnrn rnrn else if(position_end!=string::npos && appendmark==true)rn [color=#FF0000]line.copy(sentence_append, sentence_size,position_start);[/color]rn sentence.append(sentence_append);rn appendmark=false;rn rnrn else if(position_end==string::npos && appendmark==true)rn line.copy(sentence_append, sentence_size,position_start);rn sentence.append(sentence_append);rn rnrn position_start=position_end;rnrn while(position_end!=string::npos);rn cout< 论坛

没有更多推荐了,返回首页