关于vue.js:js注释包含关键字替换

8次阅读

共计 8216 个字符,预计需要花费 21 分钟才能阅读完成。

思路:

首先查找选中文本是以后 html 第几个字符,而后进行替换款式(isIE 为 true 代表的是 ie 浏览器)
1、自定义右键事件
2、获取选中的文本及文本为以后 html 第几个
3、进行替换并勾销文本选中

自定义右键事件

document.oncontentmenu = function(e){
    // 判断是否有选中的文本
    if(!this.judgeSelectText(this.getSelectedText())){return false};
    this.getSelectedTextAndCurrentNum();
    let target = e.target;
    // 判断创立菜单的类型;dom 对象 id 是否蕴含 "spanId_"
    if(
        this.selectText && 
        ((target.id && target.id.indexOf("spanId_")<0) || !target.id)){
        // 创立长期右键菜单
        this.createMenu("add",e,target)
    }else if(target.id && target.id.indexOf("spanId_") > -1){
        this.spanId = target.id;
        this.createMenu("other",e,target)
    }
}.bind(this)

// 点击正文操作
document.onmousedown = function(e){
    let target = e.target;
    // 增加正文
    if(target.id && target.id.indexOf("addAnnotate") >= -1){if(this.selectText != ""){
            //1、关上增加正文弹框,2、设置操作为增加
            this.operation = "add";    
        }else if(target.id && target.id.indexOf("updateAnnotate") >= -1){
            //1、关上批改正文弹框,2、设置操作为批改,3、申请获取正文数据值
            this.operation = "update";    
        }else if(target.id && target.id.indexOf("deleteAnnotate") >= -1){
            //1、关上删除正文弹框,2、设置操作为删除
            this.operation = "delete";    
        }else if(target.id && target.id.indexOf("viewAnnotate") >= -1){
            //1、关上查看正文弹框,2、设置操作为查看,3、申请获取正文数据值
            this.operation = "view";    
        }
    }
}.bind(this)

getSelectedText:获取选中的数据

getSelectedText(){if(isIE){
        let selectedText = "";
        if(document.selection){selectedText = document.selection.createRange().text;
        }else if(document.getSelection){selectedText = document.getSelection().toString();}else if(window.getSelection){selectedText = window.getSelection().toString();}
        return selectedText
    }else{let selectObject = window.getSelection();
        let selectedText = selectObject.toString();
        return selectedText
    }
}

judgeSelectText:判断以后选中的数据是否符合规范

judgeSelectText(selectText){
    // 判断文本是否多段
    if(selectText.indexOf("\r")>=0 || selectText.indexOf("\n")>=0){alert("多段文本不反对增加正文")
        return false;        
    }else if(window.getSelection()){
        // 判断以后选中数据是否含有正文字段
        let selection = window.getSelection();
        if(selection.anchorNode){
            //anchorNode: 返回该选区终点所在的节点
            //focusNode: 返回该选区起点所在的节点
            if(selection.anchorNode.data != selection.focusNode.data){alert("选中文本蕴含已正文的文本");
                return false
            }
        }
    }
    return true
}

getSelectedTextAndCurrentNum:获取以后选中的数据及地位放入内存

getSelectedTextAndCurrentNum(){if(isIE){
        // 以后 selection 对象
        let selectText = "";
        let selectObject = null;
        if(document.selection){
            //ie10
            selectText = document.selection.createRange().text;}else if(document.getSelection){
            //ie11
            selectText = document.getSelection().toString();
        }else if(window.getSelection){selectText = window.getSelection().toString();}
        selectObject = document.getSelection()
        if(selectText && selectText != ""){
            this.selectText = selectText;
            // 获取比拟以后地位数据进行比拟
            let compareData = this.getNowSelectionCompareData(selectObject);
            // 初始化设置以后地位为 0, 入选中文本为暗藏状态扭转后的数据(dispaly:none-->display:block);
            // 暗藏的文本计算不正确,hideCurentNum 为暗藏文本数量
            let currentNumber = 0;
            this.hideCurentNum = 0;
            // 获取以后是第几个元素
            let range = document.body.createRange();
            currentNumber = this.getIECurrentNum(range,compareData,selectText,0);
            this.currentNum = currentNumber
        }else{
            this.selectText = "";
            this.currentNum = 0
        }
    }else{let selectObject = window.getSelection();
        let selectText = selectObject.toString();
        if(selectText && selectText != ""){
            this.selectText = selectText;
            // 获取比拟以后地位数据进行比拟
            let compareData = this.getNowSelectionCompareData(selectObject);
            let currentNumber = 0;
            window.getSelection().removeAllRanges();
            currentNumber = this.getNotIECurrentNum(compareData,selectText,0);
            this.currentNum = currentNumber
        }else{
            this.selectText = "";
            this.currentNum = 0
        }
    }
}

getNowSelectionCompareData:获取比拟对象

getNowSelectionCompareData(selection){let compareData = {};
    if(selection){
        var flg = selection.anchorOffset < selection.focusOffset;
        compareData = {
            leftPoint:flg ? selection.anchorOffset : selection.focusOffset,
            rightPoint:flg ? selection.focusOffset : selection.anchorOffset,
            leftPointNode:flg ? selection.anchorNode : selection.focusNode,
            rightNode:flg ? selection.focusNode : selection.anchorNode,
        }
        return compareData;
    }
    return null;
}

getIECurrentNum:IE 浏览器计算以后选中为第几个 compareData

getIECurrentNum(text,compareData,str,n){if(text.findText(str)){
        try{text.select()
        } catch(e) {
            // 报错阐明含有暗藏文本
            this.hideCurentNum++;
            text.collapse(false);
            return this.getIECurrentNum(text,compareData,str,n)
        }
        n++;
        var tmpSelection = document.getSelection();
        if(
            tmpSelection.focusNode == compareData.rightNode &&
            tmpSelection.anchorNode == compareData.leftNode &&
            tmpSelection.anchorOffset == compareData.leftPoint &&
            tmpSelection.focusOffset == compareData.rightPoint
        ){document.body.createTextRange();
            return n;
        }else{text.collapse(false);
            return this.getIECurrentNum(text,compareData,str,n)
        }
    }else{document.body.createTextRange();
        text.findText(str);
        return 0;
    }
}

getNotIECurrentNum:获取非 ie 以后页面选中字符的地位

getNotIECurrentNum(compareData,str,n){if(window.find(str,false,false)){
        n++;
        var tmpSelection = widow.getSelection();
        if(
            tmpSelection.focusNode == compareData.rightNode &&
            tmpSelection.anchorNode == compareData.leftNode &&
            tmpSelection.anchorOffset == compareData.leftPoint &&
            tmpSelection.focusOffset == compareData.rightPoint
        ){return n;}else return this.getNotIECurrentNum(compareData,str,n)
    }else return 0
}

createMenu:创立菜单(依据 absolute 定位)

createMenu(operation,e,parentNode){
    // 屏幕宽度
    let iframeWidth = document.documentElement.clientWidth || 
    window.clientWidth || 
    document.body.clientWidth;
    // 新增时,元素间隔父元素的高度
    let topDistance = this.isIE 
      ? 10 : 
      e.clientY-parentNode.getBoundingClientRect().top;
    // 新增时,元素间隔父元素左侧间隔
    let rightDistance = parentNode.getBoundingClientReact().right - e.offsetX;
    let leftDistance;
    if(
      parentNode.targetName == "TD" ||
      parentNode.parentNode.targetName == "TD" ||
      parentNode.parentNode.parentNode.targetName == "TD"
    ){
        leftDistance = 
          parentNode.getBoundingClientRect().left < 150 
            ? e.offsetX
            : e.offsetX - 150;
    }else{
        leftDistance = 
          e.offsetX < 300
            ? e.offsetX 
            : rightDistance > 150 
            ? e.offsetX
            : e.offsetX - 150
    }
    // 编辑删除查看操作左侧间隔
    let otherLeftDistance = 
      iframeWidth - parentNode.getBoundingClientRect().right > 150
        ? 10
        : -150;
    this.removeMenu();
    if(!parentNode) return ;
    parentNode.style.position = "relative";
    let tmpDiv = document.createElement("div");
    if(operation == "add"){
        tmpDiv.className = "previewMenuDiv";
        tmpDiv.style.cssText = 
          "position:absolute;"+
          "left:"+leftDistance+"px;"+
          "top:"+topDistance+"px;"+
          "z-index:99;text-indent:0";
        tmpDiv.innerHTML = 
          "<div id='addAnnotate'> 增加正文 </div>"
    }else{
        tmpDiv.className = "previewMenuDiv";
        tmpDiv.style.cssText = 
          "position:absolute;"+
          "left:"+otherLeftDistance+"px;"+
          "z-index:99;text-indent:0";
        tmpDiv.innerHTML = 
          "<div id='viewAnnotate'> 查看正文 </div><div id='updateAnnotate'> 编辑正文 </div><div id='deleteAnnotate'> 删除正文 </div>";
    }
    if(parentNode){parentNode.appendChild(tmpDiv)
    }
    this.previewMenu = tmpDiv;
}

createMenu:移除菜单

createMenu(){if(this.previewMenu){this.preview.parentNode.removeChild(this.previewMenu);
        this.previewMenu = null
    }
}

保留正文操作
正文 id:spanId = “spanId_”+new Date().getTime();
选中文本:this.selectText;
选中数据为以后 html 第几个:currentNum;
非 ie 浏览器暗藏元素查找不到,ie 浏览器需加上暗藏元素的个数 hideCurrentNum

saveAnnotate(){if(this.isIE){
        this.replaceIEHtml(
          this.currentNum + this.hideCurrentNum,
          this.selectText,
          this.spanId
        )
    }else{
        this.replaceNotIEHtml(
          this.currentNum,
          this.selectText,
          this.spanId
        )
    }
}

replaceIEHtml:ie 浏览器替换选中的元素

replaceIEHtml(currentNum,str,spanId){var textRangeArr = [];
    var range = document.body.crateTextRange();
    textRangeArr = this.getFindTextRange(range,str);
    let newTextRangeArr = [];
    if(textRangeArr.length > 0){for(let i = 0;i<textRangeArr.length;i++){if(textRangeArr[i].offsetLeft != 0 && textRangeArr[i].offsetTop != 0){newTextRangeArr.push(textRangeArr[i])
            }
        }
    }
    if(currentNum <= textRangeArr.length){
        currentNum = currentNum > 0 ? currentNum : 1;
        var nowText = newTextRangeArr[currentNum - 1];
        var replaceSelectHtml = 
          '<span id="'+spanId+
          '"oncontextmenu="" class="annotateKeyClass" style="background:#f28109">'+
          str+"</span>";
        if(nowText){nowText.pasteHTML(replaceSelectHtml)
        }
    }
}

getFindTextRange:获取以后 ie 符合条件的 ranges

getFindTextRange(range,str){var ranges = new Array();
    var dup = range.duplicate();
    var flg = true;
    do{var d = dup.duplicate();
        if(d.findText(str)){ranges.push(d);
            dup.setEndPoint("StartToEnd",d);
            continue;
        }
        break;
    }while(flg);
    return ranges;
}

replaceNotIEHtml:非 ie 浏览器替换选中的元素

replaceNotIEHtml(currentNum,str,spanId){
    var selectText = null;
    window.getSelection().removeAllRanges();
    selectText = this.getCurrentSession(str,0,currentNum);
    if(selectText){var range = selectText.getRangeAt(0);
        var replaceTempSpan = document.createElement("span");
        replaceTempSpan.id = spanId;
        replaceTempSpan.className = "annotateKeyClass";
        replaceTempSpan.style["background"] = "#f28109";
        replaceTempSpan.innerText = str;
        range.surroundContents(replaceTempSpan)
    }
    window.getSelection().removeAllRanges();
}

getCurrentSession:获取以后正文的选中对象

getCurrentSession(str,n,currentNum){if(window.find(str,false,false)){
        n++;
        if(n == currentNum){return window.getSelection()
        }
        return this.getCurrentSession(str,n,currentNum)
    }else{return null;}
}
正文完
 0