Page text annotation

Posted by Bad HAL 9000 on Tue, 28 Dec 2021 06:19:43 +0100

Effect achieved:











There are generally two ways to realize the annotation function:

1, The back end will store the data in two parts: ① plain text in the article area ② string containing HTML structure

When the front end requests data, it will be directly returned to the front end, and the front end will display it directly.

At present, we adopt this idea, which is relatively easy to realize

2, The back end stores a large collection, including the source text and annotation information collection of the article (the starting point and ending point of multiple annotation points). The front end takes the information for processing, echo and operation. Many problems will also arise under this idea. For example, once the span tag is inserted, the length of the source text will be changed, and the recorded starting point and ending point information will be wrong

Several problems encountered during text annotation on the page:

1, Add dimension (dimension of a sliding selection)







① When the mouse slides the selection in the article, the selection area can use window Getselection() to get a selection object selObj

②selObj.toString() gets the text selected by the mouse

③selObj.getRangeAt(0) gets the range object

④range.surroundContents(ele) to the selected package

2, Remove

Remove a label (put the text to be labeled in the title, and then directly replace the DOM with it)







3, It cannot be marked outside the article area, but only in the article area







4, Annotation congener highlighting







Select all sub elements in the document area, traverse, replace the unmarked ones, obtain outerHTML for the marked ones, splice them into an overall HTML string, and replace the DOM in the article area

5, When the dimension source cancels the dimension, the highlight of the same type is also cancelled

(1) When the first and second functions are implemented separately, it is normal to add and remove, but after the four functions replace the DOM in the article area, the removal will be problematic

① Put the removal function on the outermost DOM tree. When you click a button, get the button area, and then carry out relevant operations

(2) When you click the delete button of a label, other same labels will be deleted

① Get the click point target and get the title.

let pText=e.target.parentElement.title

② Get all child nodes under the container

let dom=document.getElementById('docText').childNodes

③ Traverse the set of child nodes, filter and judge that the title is equal, and replace the node with the title text in place to realize the label after deleting the label

for(let i=0;i<dom.length;i++){

/ / only operate on labeled nodes

          if(dom[i].textContent.indexOf('*]x') > -1){

            if(dom[i].title === pText){

              dom[i].replaceWith(pText)

            }

          }

}

6, Dimension echo

The background will store the data in two parts: ① plain text in the article area ② string containing HTML structure

When the foreground requests data, it is directly returned to the foreground

Key codes:

methods: {
    toTag(value,index){
      let that = this
      let domNode = document.getElementById('docText')
      //Judge whether the selected area is in docText
      let has=window.getSelection().containsNode(domNode, true)
      if(has){//Determine whether the mouse sliding area is within the document area
        let str = value.proxy
        let selObj=window.getSelection()
        let txtString=selObj.toString()
        let spanTxt = str.slice(0,2) + txtString + str.slice(2)
        // console.log(spanTxt)
        if(txtString){
          let range=selObj.getRangeAt(0)
          // console.log(range)
          let ele=document.createElement('span')
          let eleDel=document.createElement('span')
          ele.style.backgroundColor=value.btnBgColor
          ele.className='customTag'
          ele.title=txtString
          eleDel.className='del_bt'
          eleDel.textContent='x'
          // eleDel.onclick=()=>that.toDel(ele)
          range.surroundContents(ele)
          let s='<span class="tagText">'+ spanTxt +'</span>'
          ele.innerHTML=s
          ele.appendChild(eleDel)
          //Article annotation (highlight the selected text)
          let dom=document.getElementById('docText').childNodes
          console.log(dom)
          let pingStr=''
          for(let i=0;i<dom.length;i++){
            //Homogeneous highlight
            //Those that have been marked are excluded. Only for unmarked operations
            if(dom[i].textContent.indexOf('*]x') === -1){
              let paragraph=dom[i].textContent
              let reg=new RegExp(txtString,'g')
              let t=`<span class="customTag" title="${txtString}" style="background-color: rgb(167,173,177);"><span class="tagText">${spanTxt}</span><span class="del_bt">x</span></span>`
              let replacedTxt=paragraph.replace(reg,t)
              pingStr+=replacedTxt
              // dom[i].replaceWith(replacedTxt)
              // console.log(dom[i].textContent)
            }else{
              pingStr+=dom[i].outerHTML
              // console.log(dom[i].outerHTML)
            }
          }
          // console.log(pingStr)
          document.getElementById('docText').innerHTML=pingStr
          window.getSelection().removeAllRanges()
        }
      }else{
        this.$modal.msgError("Please mark in the document area")
      }
    },
    //Click the delete button to delete all the same types
    toDel(e){
      if(e.target.className==='del_bt'){
        console.log(e.target.parentElement.title)
        let pText=e.target.parentElement.title
        console.log(document.getElementById('docText').childNodes)
        let dom=document.getElementById('docText').childNodes
        for(let i=0;i<dom.length;i++){
          //Operations on dimensions only
          if(dom[i].textContent.indexOf('*]x') > -1){
            if(dom[i].title === pText){
              dom[i].replaceWith(pText)
            }
          }
        }

      }
    }
  }

Topics: Javascript Front-end html