突出显示关键字的Textarea:奇怪的游标行为

时间:2017-10-10 12:48:23

标签: javascript jquery html textarea summernote

我正在使用Summernote插件创建一个漂亮的textarea和Mark.js插件,以突出显示该textarea中定义的关键字(例如import tkinter as tk import tkinter.ttk as ttk from widgets import ImgButton class DiceFrame(ttk.Frame): def __init__(self, master, *args, **kwargs): super().__init__(master, *args, **kwargs) current_style = 'Die.TButton' style = ttk.Style() style.configure(current_style, borderwidth=6, ) button = ImgButton(master, style=current_style) button.pack(side=tk.LEFT) if __name__ == "__main__": root = tk.Tk() DiceFrame(root).pack(side="top", fill="both", expand=True) root.mainloop() )。

我有这个HTML代码:

foo

和Javascript代码:

<div id="text"></div>

JSFiddle

它运作良好。每次用户在textarea中写$('#text').summernote({ height: 150, callbacks: { onChange: function (contents, $editable){ $('.note-editable').unmark({"done": function () { $('.note-editable').mark( 'foo', {'separateWordSearch': false }) }}) } } } ); 时,该单词都会突出显示,但是我有这个问题:当用户写foo时,光标移动到foo字的开头,我不想要这个。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

可编辑的div不是处理输入的理想类型。类似的游标行为在使用JS或jQuery显式更新可编辑div的值时很常见。要解决此问题,您需要使用合适的默认输入类型,例如<input><textarea>标记。

这并不能解决您的用例,因为您无法更改所选文本的属性。因此,客户端的解决方案如下:

  1. 创建一个全局变量,以存储每个此类可编辑div的更新游标值。
  2. 在每个onblur事件上更新此全局变量的值。
  3. 在突出显示关键字之前检索此全局值。
  4. 在进行必要的关键字突出显示后,将光标更新为检索到的值。
  5. 以下是检索和更新游标值的函数:

    function doGetCaretPosition (id, storeTo) {
      var oField = document.getElementById(id);
      // Initialize
      var iCaretPos = -1;
    
      // IE Support
      if (document.selection) {
    
        // Set focus on the element
        oField.focus();
    
        // To get cursor position, get empty selection range
        var oSel = document.selection.createRange();
    
        // Move selection start to 0 position
        oSel.moveStart('character', -oField.value.length);
    
        // The caret position is selection length
        iCaretPos = oSel.text.length;
      }
    
      // Firefox support
      else if (oField.selectionStart || oField.selectionStart == '0')
        iCaretPos = oField.selectionStart;
    
      // Return results
      if( window[storeTo] !== undefined || window[storeTo] !== '' )
      {
        //if position is not updated
        if( $(oField).val().length == iCaretPos )
            window[storeTo] = -1;
        else    
        window[storeTo] = iCaretPos; 
        console.log("[doGetCaretPosition Updated]  "+$(oField).attr('id')+" in : "+window[storeTo]);
      }
      else
        console.log("[doGetCaretPosition : failed]");
    }
    
    
    //Set caret position
    function setCaretPosition(elemId, caretPos) {
        var elem = document.getElementById(elemId);
    
        if(elem != null) {
            if(elem.createTextRange) {
                var range = elem.createTextRange();
                range.move('character', window[caretPos]);
                range.select();
            }
            else {
                if(elem.selectionStart) {
                    elem.focus();
                    elem.setSelectionRange(window[caretPos], window[caretPos]);
                }
                else
                    elem.focus();
            }
        }
        console.log( "[setCaretPosition Updated]" );
    }
    

答案 1 :(得分:1)

那是因为突出显示的文字会变成 var elementComponent = { bindings:{ selected:'<' }, controller:function($element){ this.$onChanges = function(changes) { if(changes.selected.currentValue){ $element[0].getElementsByClassName('textName')[0].focus() } } }, template:'<input type="text" class="textName" style="margin:4px">' }; var controller = function(){ this.list = [1]; this.selected = 1 this.add = function(){ var length = this.list.length ; this.list.push(length + 1); this.selected = length + 1; } }; angular.module('app', []) .component('element', elementComponent) .controller('appCtrl', controller);标签。您必须将光标设置在该标记的末尾。如果你有时间,我会在一小时内用解决方案更新这篇文章。