1. 程式人生 > >奇技淫巧——在textarea中插入文字

奇技淫巧——在textarea中插入文字

本文首發我的簡書

今天在看自己的記錄時發現在幾個月前的一個專案中碰到一個這樣的需求:做一些簡單的計算按鈕,點選這些按鈕之後就在後面的輸入框中顯示對應的計算方法,對於一些函式類的計算方法需要將游標定位在括號裡面,效果如下圖:

當時也是第一次碰到這種需求,我搜集了網路上的一些資料最終解決這個問題,現將這個小技巧整理一下以備日後查閱。
本文的關鍵點:在游標後插入文字的方法(來源https://blog.csdn.net/liushuijinger/article/details/48834541

        function insertAtCursor(myField, myValue) {
            //IE 瀏覽器  
            if (document.selection
) { myField.focus(); sel = document.selection.createRange(); sel.text = myValue; sel.select(); } //FireFox、Chrome等 else if (myField.selectionStart || myField.selectionStart == '0') { var startPos = myField.selectionStart
; var endPos = myField.selectionEnd; // 儲存滾動條 var restoreTop = myField.scrollTop; myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length); if (restoreTop > 0
) { myField.scrollTop = restoreTop; } myField.focus(); myField.selectionStart = startPos + myValue.length; myField.selectionEnd = startPos + myValue.length; } else { myField.value += myValue; myField.focus(); } }

該方法中有兩個引數myField與myValue,前者指當前輸入框dom元素,類似jQuery中的$('textarea')[0],第二個引數myValue指的是需要插入的字串。而這個方法做了什麼事呢,首先它獲取了當前textarea/input中的游標位置,然後在這個位置上插入了一段字串,最後記錄了游標變更後的位置。
本文的另一個關鍵點——設定游標的位置(點選某些帶括號的方法,游標在括號中)

        function setCaretPosition(textDom, pos){
            if(textDom.setSelectionRange){//chrome/firefox
                textDom.focus();
                textDom.setSelectionRange(pos,pos);
            }else if (textDom.createTextRange) {//IE
                var range = textDom.createTextRange();
                range.collapse(true);
                range.moveEnd('character', pos);
                range.moveStart('character', pos);
                range.select();
            }
        }

該方法的第一個引數表示當前顯示內容的輸入框dom元素,第二個引數表示游標要偏移的量(number)。(以上方法根據度娘搜尋整合)
最後附上完整程式碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        body{
            margin-top: 50px;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <button class="calcbtn easycalc addFunc"></button>
    <button class="calcbtn easycalc cutFunc"></button>
    <button class="calcbtn easycalc multiFunc"></button>
    <button class="calcbtn easycalc divisionFunc"></button>
    <button class="calcbtn abs">絕對值</button>
    <button class="calcbtn pow2">平方</button>
    <button class="calcbtn pow-2">開方</button><br/>
    <textarea id="logicScript" type="text" placeholder="請點選上方輔助按鈕或直接輸入計算方法"></textarea><br>
    <input type="text" id="text">
    <button id="insertbtn">點選插入文字</button>
    <script src="./js/jquery.min.js"></script>
    <script>
        $(function(){
            $('.calcbtn').on('click',function(){
                if($(this).hasClass('easycalc')){
                    if($(this).hasClass('addFunc')){
                        var str = '+';
                    }else if($(this).hasClass('cutFunc')){
                        var str = '-';
                    }else if($(this).hasClass('multiFunc')){
                        var str = '*';
                    }else if($(this).hasClass('divisionFunc')){
                        var str = '/';
                    }
                    var oriStr = $('#logicScript').val();
                    $('#logicScript').val(oriStr+str);
                    $('#logicScript')[0].focus();
                }else if($(this).hasClass('abs')){
                    var str = 'abs()';
                    handlelogicScript(str,-1);
                }else if($(this).hasClass('pow2')){
                    var str = 'pow(,2)';
                    handlelogicScript(str,-3);
                }else if($(this).hasClass('pow-2')){
                    var str = 'sqrt()';
                    handlelogicScript(str,-1);
                }
            })
            $('#insertbtn').on('click',function(){
                var myField = $('#logicScript')[0];
                var myValue = $('#text').val();
                insertAtCursor(myField,myValue);
            })
        // 設定游標位置
        function setCaretPosition(textDom, pos){
            if(textDom.setSelectionRange){//chrome/firefox
                textDom.focus();
                textDom.setSelectionRange(pos,pos);
            }else if (textDom.createTextRange) {//IE
                var range = textDom.createTextRange();
                range.collapse(true);
                range.moveEnd('character', pos);
                range.moveStart('character', pos);
                range.select();
            }
        }
        //獲取游標的位置
        function getCursortPosition(textDom){
            var cursorPos = 0;
            cursorPos = textDom.selectionStart;
            return cursorPos;
        }
        //處理顯示的內容
        function handlelogicScript(str,offset){
            var oriStr = $('#logicScript').val();
            $('#logicScript').val(oriStr+str);
            var target = $('#logicScript')[0]
            target.focus();
            //獲取游標最初的位置(末尾)
            var oriPos = getCursortPosition(target);
            //設定游標真正的位置
            var pos = oriPos+offset;
            setCaretPosition(target,pos);
        }

        //在游標後插入文字
        function insertAtCursor(myField, myValue) {
            //IE 瀏覽器  
            if (document.selection) {  
                myField.focus();  
                sel = document.selection.createRange();
                sel.text = myValue;  
                sel.select();  
            }
             //FireFox、Chrome等  
            else if (myField.selectionStart || myField.selectionStart == '0') {  
                var startPos = myField.selectionStart;  
                var endPos = myField.selectionEnd; 
                // 儲存滾動條  
                var restoreTop = myField.scrollTop;  
                myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);  
                if (restoreTop > 0) {  
                    myField.scrollTop = restoreTop;  
                }  
                myField.focus();  
                myField.selectionStart = startPos + myValue.length;  
                myField.selectionEnd = startPos + myValue.length;
            } else {  
                myField.value += myValue;
                myField.focus();
            }  
        }  
    })
</script>
</body>
</html>