Matching and highlighting tags/words (changing color and font-weight) inside textarea using jQuery

后端 未结 4 1098
后悔当初
后悔当初 2021-01-25 10:31

I\'ve textarea where I just start typing when I add tags which I define in array so based on my condition it should say in array but it is

4条回答
  •  日久生厌
    2021-01-25 11:12

    1) Your code doesn't work since you read the value of textarea once and this variable is not changing while you are typing;

    2) Using $.inArray(txtArea, tagsArray) you are trying to if the full string is contained in the array which is not correct. Using RegExp for this would be much better:

    $(document).ready(function() {
        var tagsArray = new Array("{full_name}", "{email}", "{company}");   
        $('textarea#txtarea').on('keyup', function() {
            var val = $(this).val();
            var searchExp = new RegExp(tagsArray.join("|"),"gi");
            if(searchExp.test(val)) {
                console.log("in array");
            } else {
                console.log("not in array");
            }
        });
    });
    
    

    3) You can't apply styling to the separate words withing the textarea. See this question. Probably you will need to have some other approach, for example something like this - the idea here is to have a div element as background and sync content between this element and textarea.

    UPDATE: 4) You can try to use contenteditable="true" on the div element and this will the inner content editable, so your div could behave like a rich text editor. Here is a quick example on how this could be achieved. Hope this idea will help you (I'm not going to write the full functionality for you, just want to illustrate the concept and what options do you have with your issue).

    $(document).ready(function() {
        var tagsArray = new Array("{full_name}", "{email}", "{company}");   
        $('div#txtarea').on('keyup', function() {
            var $this = $(this); 
            //remember position of cursor before changing the content of the div element
            var restoreCursorPosition = saveCaretPosition(this);
            var val = $this.text(); 
    
            //highlight tags
            $this.html(val.replace(new RegExp(tagsArray.join("|"), "gi"), "$&"));
            //resore cursor position
            restoreCursorPosition();
        });
        
        function saveCaretPosition(context){
            var selection = window.getSelection();
            var range = selection.getRangeAt(0);
            range.setStart(context, 0 );
            var len = range.toString().length;
    
            return function restore(){
                var pos = getTextNodeAtPosition(context, len);
                selection.removeAllRanges();
                var range = new Range();
                range.setStart(pos.node ,pos.position);
                selection.addRange(range);
    
            }
        }
    
        function getTextNodeAtPosition(root, index){
            var lastNode = null;
    
            var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT,function next(elem) {
                if(index > elem.textContent.length){
                    index -= elem.textContent.length;
                    lastNode = elem;
                    return NodeFilter.FILTER_REJECT
                }
                return NodeFilter.FILTER_ACCEPT;
            });
            var c = treeWalker.nextNode();
            return {
                node: c? c: root,
                position: c? index:  0
            };
        }
    });
    div#txtarea {
      width: 150px;
      height: 150px;
      border: 1px solid black;
      overflow: auto;
    }
    
    mark {
      color: blue;
      font-weight: bold;
      background: transparent
    }
    
    
    Test input!

提交回复
热议问题