浮动到表格中某一行,根据改行信息高亮某区域文字,并设置对应滚动高度,使高亮文字出现在当前视野

第一版:事先说明,此代码结合应用项目场景,故这里的代码很难理解,纯本人笔记

            highlightOpinion: function (opinion) {
                $scope.mark.highlightContent = $scope.mark.highlightContentStore;//highlightContentStore是后台接受不带高亮效果的文字

                var reg = new RegExp();
                var replaceStr = '';
                for (var k in opinion) {
                    if (k == '评论关键字') {
                        if (opinion[k] !== ' ' && opinion[k] !== '/') {
                            reg = new RegExp(opinion[k], 'ig');
                            replaceStr = `<span class="color-bg-green">${opinion[k]}</span>`;
                            $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr);
                        }
                    } else if (k == '评论小类') {
                        if (opinion[k] !== ' ' && opinion[k] !== '/') {
                            reg = new RegExp(opinion[k], 'ig');
                            replaceStr = `<span class="color-bg-blue">${opinion[k]}</span>`;
                            $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr);
                        }
                    }
                }

                //滚动条移动到该词语
                var ele = document.getElementById('textarea2');
                var scrollHeight = ele.scrollHeight,
                    totalStrLength = ele.value.length,
                    currentStr = ele.value.toLowerCase().indexOf(opinion['评论关键字'].toLowerCase()) == -1 ?
                     ele.value.toLowerCase().indexOf(opinion['评论小类'].toLowerCase()) : 
                     ele.value.toLowerCase().indexOf(opinion['评论关键字'].toLowerCase());
                $timeout(function () {
                    if (currentStr == -1) return; //说明原文中不包含评论关键字和评论小类
                    var eleCopy = document.getElementById('textarea2-copy');
                    eleCopy.scrollTop = (scrollHeight * currentStr / totalStrLength - 20 > 0) ? (scrollHeight * currentStr / totalStrLength - 20) : (currentStr / totalStrLength);
                }, 0);
                $scope.mark.showHighlight = true;
            },

 效果:

附加浮动到某列。并且定位当前列和高亮当前列的方法

//item为该行的数据,tdIndex为列的位置,程序中的answerColumnName代表所有列名,answerColumnName【tdIndex】则对应该列的列名,也是该列字段的key

  highlightOpinion: function (item, tdIndex) { $scope.mark.highlightContent = $scope.mark.highlightContentStore;//highlightContentStore是后台接收的不带高亮效果的文字 var reg = new RegExp(); var replaceStr = ''; var ele = document.getElementById('textarea2'); var scrollHeight = ele.scrollHeight, totalStrLength = ele.value.length, currentStr = -1; if (tdIndex >= 0) { if (item[$scope.mark.answerColumnName[tdIndex]] !== ' ' && item[$scope.mark.answerColumnName[tdIndex]] !== '/') { currentStr = ele.value.toLowerCase().indexOf(item[$scope.mark.answerColumnName[tdIndex]].toLowerCase()); } } if (tdIndex >= 0 && currentStr != -1) { //浮动到具体某列,并且该列在原文中出现,那么先高亮当前列,再高亮所有列(此时currentStr!=-1代表已定位到当前列) reg = new RegExp(item[$scope.mark.answerColumnName[tdIndex]], 'ig'); replaceStr = `<span class="answer-column-color-bg-${tdIndex + 1}">${item[$scope.mark.answerColumnName[tdIndex]]}</span>`; $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr); for (var i = 0; i < $scope.mark.answerColumnName.length; i++) { var keyName = $scope.mark.answerColumnName[i]; if (item[keyName] !== ' ' && item[keyName] !== '/') { reg = new RegExp(item[keyName], 'ig'); replaceStr = `<span class="answer-column-color-bg-${i + 1}">${item[keyName]}</span>`; $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr); } } } else { //没浮动到具体某列,那么高亮所有列,定位到在原文中出现的第一列 for (var i = 0; i < $scope.mark.answerColumnName.length; i++) { var keyName = $scope.mark.answerColumnName[i]; if (item[keyName] !== ' ' && item[keyName] !== '/') { reg = new RegExp(item[keyName], 'ig'); replaceStr = `<span class="answer-column-color-bg-${i + 1}">${item[keyName]}</span>`; $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr); } } for (var i = 0; i < $scope.mark.answerColumnName.length; i++) { var keyName = $scope.mark.answerColumnName[i]; if (item[keyName] !== ' ' && item[keyName] !== '/') { currentStr = ele.value.toLowerCase().indexOf(item[keyName].toLowerCase()); if (currentStr !== -1) break; } } } $timeout(function () { if (currentStr == -1) return; //说明原文中不包含老答案字段 var eleCopy = document.getElementById('textarea2-copy'); eleCopy.scrollTop = (scrollHeight * currentStr / totalStrLength - 50 > 0) ? (scrollHeight * currentStr / totalStrLength - 50) : (scrollHeight * currentStr / totalStrLength - 20 > 0) ? (scrollHeight * currentStr / totalStrLength - 20) : (currentStr / totalStrLength); }, 0); $scope.mark.showHighlight = true; },

 第二版: 列浮动的升级:

升级的意义:因为列中可能包含*?+等正则表达式的敏感字段,所以需要先将这些字段进行处理,才能正确的生成正则表达式

            //处理字符串中可能对正则有影响的字符串
            escapeString(value) {
                let str = value.replace(new RegExp('\\', 'g'), '\\');
                let characterss = ['(', ')', '[', ']', '{', '}', '^', '$', '|', '?', '*', '+', '.'];
                characterss.forEach((characters) => {
                    var r = new RegExp('\' + characters, 'g')
                    str = str.replace(r, '\' + characters)
                })
                return str;
            },
//浮动高亮 highlightOpinion: function (item, tdIndex) { $scope.mark.highlightContent = $scope.mark.highlightContentStore;//highlightContentStore是后台接收的不带高亮效果的文字 var reg = new RegExp(); var replaceStr = ''; var ele = document.getElementById('textarea2'); var scrollHeight = ele.scrollHeight, totalStrLength = ele.value.length, currentStr = -1; if (tdIndex >= 0) { if (item[$scope.mark.answerColumnName[tdIndex]] !== ' ' && item[$scope.mark.answerColumnName[tdIndex]] !== '/') { currentStr = ele.value.toLowerCase().indexOf(item[$scope.mark.answerColumnName[tdIndex]].toLowerCase()); } } if (tdIndex >= 0 && currentStr != -1) { //浮动到具体某列,并且该列在原文中出现,那么先高亮当前列,再高亮所有列(此时currentStr!=-1代表已定位到当前列) var resStr = $scope.mark.escapeString(item[$scope.mark.answerColumnName[tdIndex]]) reg = new RegExp(resStr, 'ig'); replaceStr = `<span class="answer-column-color-bg-${tdIndex + 1}">${item[$scope.mark.answerColumnName[tdIndex]]}</span>`; $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr); for (var i = 0; i < $scope.mark.answerColumnName.length; i++) { var keyName = $scope.mark.answerColumnName[i]; if (item[keyName] !== ' ' && item[keyName] !== '/') { var resStr = $scope.mark.escapeString(item[keyName]) reg = new RegExp(resStr, 'ig'); replaceStr = `<span class="answer-column-color-bg-${i + 1}">${item[keyName]}</span>`; $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr); } } } else { //没浮动到具体某列,那么高亮所有列,定位到在原文中出现的第一列 for (var i = 0; i < $scope.mark.answerColumnName.length; i++) { var keyName = $scope.mark.answerColumnName[i]; if (item[keyName] !== ' ' && item[keyName] !== '/') { var resStr = $scope.mark.escapeString(item[keyName]) reg = new RegExp(resStr, 'ig'); replaceStr = `<span class="answer-column-color-bg-${i + 1}">${item[keyName]}</span>`; $scope.mark.highlightContent = $scope.mark.highlightContent.replace(reg, replaceStr); } } for (var i = 0; i < $scope.mark.answerColumnName.length; i++) { var keyName = $scope.mark.answerColumnName[i]; if (item[keyName] !== ' ' && item[keyName] !== '/') { currentStr = ele.value.toLowerCase().indexOf(item[keyName].toLowerCase()); if (currentStr !== -1) break; } } } $timeout(function () { if (currentStr == -1) return; //说明原文中不包含老答案字段 var eleCopy = document.getElementById('textarea2-copy'); eleCopy.scrollTop = (scrollHeight * currentStr / totalStrLength - 40 > 0) ? (scrollHeight * currentStr / totalStrLength - 40) : (scrollHeight * currentStr / totalStrLength - 20 > 0) ? (scrollHeight * currentStr / totalStrLength - 20) : (currentStr / totalStrLength); }, 0); $scope.mark.showHighlight = true; }, //取消浮动高亮 deleteHighlightOpinion: function () { $scope.mark.showHighlight = false; },

第三版:点击行高亮方法封装

            /**
             * 浮动高亮
             * @param rowObj:选中的行内容对象
             * @param columnsTitle: 列名,注意列名都是行对象的key值
             * @param mainContent:要高亮的文字
             * @returns arr:arr[0]:高亮后的文字,arr[1]:第一个高亮词的位置
             */
            highlightOpinion: function (rowObj, columnsTitle, mainContent) {
                var highlightContent = mainContent; //高亮文字
                var currentStr = -1;  //第一个高亮词的位置
                var reg = new RegExp();
                var replaceStr = '';
                //高亮
                for (var i = 0; i < columnsTitle.length; i++) {
                    var keyName = columnsTitle[i];
                    if (rowObj[keyName] != '' && rowObj[keyName] != null && rowObj[keyName] != ' ' && rowObj[keyName] !== '/') {
                        var resStr = $scope.mark.escapeString(rowObj[keyName])
                        reg = new RegExp(resStr, 'ig');
                        replaceStr = `<span class="answer-column-color-bg-${i + 1}">${rowObj[keyName]}</span>`;
                        highlightContent = highlightContent.replace(reg, replaceStr);
                        var highlightIndex = mainContent.toLowerCase().indexOf(rowObj[keyName].toLowerCase());
                        if (highlightIndex != -1 && currentStr == -1) {
                            currentStr = highlightIndex; //只取第一个高亮位置
                        }
                    }
                }
                var arr = [];
                arr.push(highlightContent);
                arr.push(currentStr);
                return arr;
            },
            highlightMarkedArea(rowObj, columnsTitle, initContent) {
                var arr = $scope.mark.highlightOpinion(rowObj, columnsTitle, initContent);
                $scope.mark.markContent = arr[0];
                if (arr[1] != -1) {  //有高亮的位置,gundong滚动到第一个高亮位置
                    var currentStr = arr[1];
                    var eleCopy = document.getElementById('marked-area');
                    var scrollHeight = eleCopy.scrollHeight;
                    var totalStrLength = $scope.mark.markContentStore.length;
                    eleCopy.scrollTop = (scrollHeight * currentStr / totalStrLength - 90 > 0) ? (scrollHeight * currentStr / totalStrLength - 90) :
                        (scrollHeight * currentStr / totalStrLength - 40 > 0) ? (scrollHeight * currentStr / totalStrLength - 40) : (currentStr / totalStrLength);
                }
            },
用:
            //选中、取消选中操作
            clickHighlightOpinion: function (answer, index) {
                /* 点击时其他行取消选中,本行取反 */
                $scope.mark.opinionCheckList = $scope.mark.opinionCheckList.map(function (item, index2) {
                    if (index2 === index) {
                        item.checked = !item.checked;
                    } else {
                        item.checked = false;
                    }
                    return item;
                });
                /* 如果选中就高亮,不选择则显示原内容 */
                if (answer.checked) {
                    var arr = $scope.mark.highlightOpinion2(answer, $scope.mark.answerColumnName, $scope.mark.highlightContentStore);
                    $scope.mark.mainContent = arr[0];
                    if (arr[1] != -1) {  //有高亮的位置,gundong滚动到第一个高亮位置
                        var currentStr = arr[1];
                        var eleCopy = document.getElementById('main-content');
                        var scrollHeight = eleCopy.scrollHeight;
                        var totalStrLength = $scope.mark.highlightContentStore.length;
                        $timeout(function () {
                            eleCopy.scrollTop = (scrollHeight * currentStr / totalStrLength - 90 > 0) ? (scrollHeight * currentStr / totalStrLength - 90) :
                                (scrollHeight * currentStr / totalStrLength - 40 > 0) ? (scrollHeight * currentStr / totalStrLength - 40) : (currentStr / totalStrLength);
                        }, 0);
                    }
                } else {
                    $scope.mark.mainContent = $scope.mark.highlightContentStore;
                }
            }


原文地址:https://www.cnblogs.com/XHappyness/p/7922032.html