zoukankan      html  css  js  c++  java
  • 点选词高亮算法

      开发项目的过程中要求做一个点击词选定一句话的功能,当时想了好多办法并且复杂化了,现在整理下思路,其实总共就几个部分:

      1、点击词的位置记录,首个词和末尾词的位置

      2、将选定词高亮

      3、有2个词后,再次选词的逻辑

      下面就来代码:

    <!DOCTYPE html>
    <html ng-app='myApp'>
        <head>
            <meta charset='utf-8'>
            <script src='angular.js'></script>
            <script src='jquery-1.11.3.js'></script>
            <style>
                .margin-r-10 {
                    margin-right: 10px;
                }
                .word {
                    margin-right: 5px;
                    cursor: pointer;
                }
                .selected {
                    background-color: #63a855;
                    color: #fff;
                }
            </style>
        </head>
        <body>
            <div ng-controller='myCtrl'>
                <ul>
                    <li ng-repeat="sentence in textContent">
                        <span class='margin-r-10'>{{sentence.role}}</span>
                        <span class="word cursor-pointer" ng-repeat="word in sentence.textContent" title="{{$parent.$index+'_'+$index}}"
                        ng-click="selectWord($parent.$index, $index)" ng-class="{selected:word.selected}">{{word.word}}</span>
                    </li>
                </ul>
            </div>
            <script>
                angular.module("myApp",[])
                .controller("myCtrl",function($scope){
                    //文本数据
                    $scope.textContent = [];
                    var chars = '呃苏先生您好我这边是应答人寿的客户服务人员.感谢您对我公司的信任最近在福建很会.购买了我公司的安康宝两全保险分红型.附加安康保提前给付重大疾病保险.为了保障您的权益我们购买了我公司保险产品的客户.都会进行售后回访,服务.现在这样您几分钟您看方便吗?';
                    var arr = chars.split('');
                    var len = arr.length;
                    var wordId = 0;
                    for (var i = 0; i < 30; i++) {
                        var textContent = [];
                        for (var k = 0; k < Math.floor(Math.random() * 1000) % 100; k++) {
                            var word = '';
                            for (var j = 0; j < Math.floor(Math.random() * 10) % 5; j++) {
                                word += arr[Math.floor(Math.random() * 1000) % len];
                            }
                            textContent.push({word: word, id: wordId});
                            wordId++;
                        }
                        var role = Math.round(Math.random()) == 0 ? 'A' : 'B';
                        $scope.textContent.push({role: role, textContent: textContent});
                    }
                    
                    //记录文本中选择词的位置的数组,最多纪录两个
                    $scope.selectWordsArr = [];
    
                    /**
                     * 选择文本内容方法
                     */
                    $scope.selectWord = function (parentIndex, index) {
                        var wordInfo = {s:parentIndex,w:index};
                        //如果arr为空,则直接压入
                        if($scope.selectWordsArr.length == 0) {
                            $scope.selectWordsArr.push(wordInfo);
                            //高亮该词
                            $scope.highLightFnc($scope.selectWordsArr, true);
                        } 
                        //否则判断当前点击是否存在于arr中,判断是否点击相同节点,如果是,则取消高亮
                        else if($scope.selectWordsArr.length == 1) {
                            //如果arr长度为1,说明只有一个词
                            if($scope.isInSignWordArr($scope.selectWordsArr, wordInfo)) {
                                //如果arr中存在相同词,说明再次点击,则取消该词高亮
                                $scope.highLightFnc($scope.selectWordsArr, false);
                                //并移出数组
                                $scope.selectWordsArr = $scope.removeWordFromArrFnc($scope.selectWordsArr, wordInfo);
                            }else{
                                //否则,将该词信息压入arr
                                $scope.selectWordsArr.push(wordInfo);
                                //排序,方便后面操作
                                $scope.selectWordsArr = $scope.sortArr($scope.selectWordsArr);
                                //高亮该区间
                                $scope.highLightFnc($scope.selectWordsArr, true);
                            }
                        } 
                        //如果数组中已有2个,则对第三个点击词进行判断
                        else if ($scope.selectWordsArr.length == 2) {
                            //如果点击词的位置小于arr中较小位置,则进行对较小位置替换
                            //如果点击词的位置大于arr中较大位置,则对较大值进行替换
                            //如果点击词存在于arr中,则进行区间取消高亮,后将相同词移除,单个词高亮
                            if($scope.isInSignWordArr($scope.selectWordsArr, wordInfo)) {
                                //当前词存在,取消区间高亮
                                $scope.highLightFnc($scope.selectWordsArr, false);
                                //将对应词移出数组
                                $scope.selectWordsArr = $scope.removeWordFromArrFnc($scope.selectWordsArr, wordInfo);
                                //设置剩余单词高亮
                                $scope.highLightFnc($scope.selectWordsArr, true);                            
                            } else {
                                //进行区间外的判断,如果小于小值,则替换小值,否则什么都不做
                                if(wordInfo.s < $scope.selectWordsArr[0].s){
                                    //如果行小于,直接记录小值
                                    $scope.selectWordsArr[0] = wordInfo;
                                }else if(wordInfo.s == $scope.selectWordsArr[0].s && wordInfo.w < $scope.selectWordsArr[0].w) {
                                    //行等于且词小于才记录
                                    $scope.selectWordsArr[0] = wordInfo;
                                }
                                //进行区间外判断,大于大值则替换,否则什么都不做
                                if(wordInfo.s > $scope.selectWordsArr[1].s){
                                    //行大于直接记录
                                    $scope.selectWordsArr[1] = wordInfo;
                                }else if (wordInfo.s == $scope.selectWordsArr[1].s && wordInfo.w > $scope.selectWordsArr[1].w){
                                    //行等于且词位置大于才记录
                                    $scope.selectWordsArr[1] = wordInfo;
                                    
                                }
                                //处理完后,高亮该区间
                                $scope.highLightFnc($scope.selectWordsArr, true);
                            }
                        }
                        angular.forEach($scope.selectWordsArr, function (obj, i) {                    
                            console.dir(i+ ' : '+obj.s+'_'+obj.w);
                        })            
                    }
                    
                    //判断当前点是否存在于已纪录词位置的数组中
                    $scope.isInSignWordArr = function(arr, data) {
                        var isIn = false;
                        angular.forEach(arr, function (obj) {
                            if(obj.s == data.s && obj.w == data.w) {
                                isIn = true;
                                return;
                            }
                        })
                        return isIn;
                    }
                    
                    //将对应词位置从数组中移除
                    $scope.removeWordFromArrFnc = function (arr, data) {
                        var sub = 0;
                        angular.forEach(arr, function (obj, i) {
                            if(obj.s == data.s && obj.w == data.w) {
                                sub = i;
                                return;
                            }
                        })
                        arr.splice(sub, 1);
                        return arr;
                    }
                    
                    //对位置数组进行排序操作,小在前,大在后,并返回
                    $scope.sortArr = function (arr) {
                        var maxSub,minSub;
                        if(arr[0].s> arr[1].s){
                            //如果前者大
                            maxSub = 0;
                            minSub = 1;
                        }else if(arr[0].s == arr[1].s){
                            //句子行数相同,判断词位置
                            if(arr[0].w>arr[1].w){
                                //如果前者大
                                maxSub = 0;
                                minSub = 1;
                            } else {
                                //否则后者大
                                maxSub = 1;
                                minSub = 0;
                            }
                        } else {
                            //否则后者大
                            maxSub = 1;
                            minSub = 0;
                        }
                        return [arr[minSub],arr[maxSub]];
                    }
                    
                    //高亮或取消对应文本位置
                    $scope.highLightFnc = function (arr, highLight) {
                        //如果arr中词为一个,则对一个词进行是否高亮
                        if(arr.length == 1){
                            $scope.textContent[arr[0].s].textContent[arr[0].w].selected = highLight;
                        } else {
                            if(arr[0].s == arr[1].s) {
                                //同一行
                                for(var i = arr[0].w; i <= arr[1].w; i++) {
                                    $scope.textContent[arr[1].s].textContent[i].selected = highLight;
                                }
                            }else {
                                //不同行操作
                                for(var i = arr[0].s; i <= arr[1].s; i ++) {
                                    for(var j = 0; j < $scope.textContent[i].textContent.length; j ++) {
                                        if(i == arr[0].s) {
                                            if(j >= arr[0].w){
                                                //如果遍历的是选择前词的行,则判断从选词开始高亮或取消
                                                $scope.textContent[i].textContent[j].selected = highLight;
                                            }
                                        } else if(i == arr[1].s) {
                                            if(j <= arr[1].w){
                                                //如果遍历的是选择后词的行,则判断从0位置搭配选词结束高亮或取消
                                                $scope.textContent[i].textContent[j].selected = highLight;    
                                            }                                    
                                        } else {
                                            //否则就高亮或取消
                                            $scope.textContent[i].textContent[j].selected = highLight;    
                                        }
                                    }
                                }
                            }
                        }
                    }
                })
            </script>
        </body>
    </html>
  • 相关阅读:
    论文总结
    20179212 2017-2018-2 《密码与安全新技术》课程总结
    20179212 2017-2018-2 《密码与安全新技术》第6周作业
    SM234
    2017-2018-2 20179212 《网络攻防》 作业
    20179212 2017-2018-2 《密码与安全新技术》第5周作业
    第十周作业 缓冲区溢出攻防研究
    密码与安全新技术
    9th
    8th
  • 原文地址:https://www.cnblogs.com/guofan/p/7692605.html
Copyright © 2011-2022 走看看