简体   繁体   English

在 CodeMirror 文本区域的插入符号处插入文本

[英]Insert Text at Caret on CodeMirror Textarea

I am working on a Python editor and would like to add a feature to insert text at the position of the caret on a CodeMirror textarea.我正在使用 Python 编辑器,并希望添加一项功能以在 CodeMirror 文本区域的插入符号位置插入文本。

There is a series of pictures which can be clicked.有一系列的图片可以点击。 When one is clicked, the alt attribute of that picture gets saved, and then when you click again inside the textarea it gets copied to your mouse position (a demo fiddle: https://jsfiddle.net/t0k7yp7n/1/ )单击时,该图片的alt属性将被保存,然后当您再次在 textarea 内单击时,它会被复制到您的鼠标位置(演示小提琴: https : //jsfiddle.net/t0k7yp7n/1/

Here is a script for the text insertion part:这是文本插入部分的脚本:

selected = '';

$('.insert').click(function() {
    console.log($(this).attr('alt'));
    selected = $(this).attr('alt');
});

$('#textbox').click(function() {
    insertAtCaret('textbox', selected)
        // Clear the selection so it isn't copied repeatedly
    selected = '';
});

function insertAtCaret(areaId, text) {
    var txtarea = document.getElementById(areaId);
    var scrollPos = txtarea.scrollTop;
    var strPos = 0;
    var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
        "ff" : (document.selection ? "ie" : false));
    if (br == "ie") {
        txtarea.focus();
        var range = document.selection.createRange();
        range.moveStart('character', -txtarea.value.length);
        strPos = range.text.length;
    } else if (br == "ff") strPos = txtarea.selectionStart;

    var front = (txtarea.value).substring(0, strPos);
    var back = (txtarea.value).substring(strPos, txtarea.value.length);
    txtarea.value = front + text + back;
    strPos = strPos + text.length;
    if (br == "ie") {
        txtarea.focus();
        var range = document.selection.createRange();
        range.moveStart('character', -txtarea.value.length);
        range.moveStart('character', strPos);
        range.moveEnd('character', 0);
        range.select();
    } else if (br == "ff") {
        txtarea.selectionStart = strPos;
        txtarea.selectionEnd = strPos;
        txtarea.focus();
    }
    txtarea.scrollTop = scrollPos;
}

And here is the CodeMirror textarea part:这是 CodeMirror textarea 部分:

 var editor; //<![CDATA[ window.onload = function() { editor = CodeMirror.fromTextArea(document.getElementById('textbox'), { mode: { name: "python", version: 2, singleLineStringErrors: false }, lineNumbers: true, indentUnit: 4 }); } //]]>
 <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script> <script src="http://www.skulpt.org/static/skulpt.min.js" type="text/javascript"></script> <script src="http://www.skulpt.org/static/skulpt-stdlib.js" type="text/javascript"></script> <script src="https://www.cs.princeton.edu/~dp6/CodeMirror/lib/codemirror.js" type="text/javascript"></script> <script src="https://www.cs.princeton.edu/~dp6/CodeMirror/mode/python/python.js" type="text/javascript"></script> <script src="skulpt-codemirror.js" type="text/javascript"></script> <script src="load-save-py.js" type="text/javascript"></script> <script src="insert.js" type="text/javascript"></script> <link href="https://www.cs.princeton.edu/~dp6/CodeMirror/lib/codemirror.css" rel="stylesheet" type="text/css"> <title>Python Editor</title> </head> <body> Filename: <input id="inputFileNameToSaveAs"> <button onclick="saveTextAsFile()">Save</button> <br> <input type="file" id="fileToLoad"> <button onclick="loadFileAsText()">Open</button> <br> <br> <a href="#!"> <img class="insert" alt="#1"> <img class="insert" alt="#2"> <img class="insert" alt="#3"> </a> <br> <br> <textarea id="textbox" name="textbox"></textarea> <br> <button onclick="runit()" type="button">Run</button> <pre id="dynamicframe"></pre> <div id="canvas"></div> </body> </html>

When I put them together in one file, though, when I click the pictures their alt s do not copy over to the textarea.但是,当我将它们放在一个文件中时,当我单击图片时,它们的alt不会复制到文本区域。 Why is this and how do I fix it?这是为什么,我该如何解决?

When using CodeMirror, your <textarea /> will be visually replaced by an editor provided by CodeMirror and most of your code relative to your <textarea /> won't be usable as is.使用 CodeMirror 时,您的<textarea />将在视觉上被 CodeMirror 提供的编辑器替换,并且与您的<textarea />相关的大部分代码将无法按原样使用。

What's going on on the background is that your actual <textarea /> will first be marked with a style display: none;背景中发生的事情是您实际的<textarea />将首先用样式display: none;进行标记display: none; . . Not displayed, no event binded on the <textarea /> will actually trigger.不显示,绑定在<textarea />上的事件不会实际触发。 Then, CodeMirror will actually add his own code to the DOM to display a new editor at the position of your <textarea /> which is now not displayed.然后,CodeMirror 实际上会将自己的代码添加到 DOM 中,以在您现在未显示的<textarea />位置显示一个新的编辑器。

For example, the HTML code for a newly initialized CodeMirror editor with the string 'Hello World' written in it would looks like:例如,新初始化的 CodeMirror 编辑器的 HTML 代码,其中写入了字符串“Hello World”,如下所示:

<div class="CodeMirror-lines">
    <div style="position: relative; outline: none;">
        <div class="CodeMirror-measure">
            <div style="width: 50px; height: 50px; overflow-x: scroll;"></div>
        </div>
        <div class="CodeMirror-measure"></div>
        <div style="position: relative; z-index: 1;"></div>
        <div class="CodeMirror-cursors">
            <div class="CodeMirror-cursor" style="left: 74px; top: 0px; height: 13px;">&nbsp;</div>
        </div>
        <div class="CodeMirror-code">
            <div style="position: relative;">
                <div class="CodeMirror-gutter-wrapper" style="position: absolute; left: -29px;">
                    <div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 20px;">1</div>
                </div><pre><span style="padding-right: 0.1px;"><span class="cm-variable">Hello</span> <span class="cm-variable">World</span></span></pre></div>
        </div>
    </div>
</div>

Your <textarea /> is no longer being used.您的<textarea />不再被使用。

CodeMirror provides natively a programming API which can be used to do what you want. CodeMirror 本身提供了一个编程 API,可以用来做你想做的事。 Basically, the steps required are:基本上,所需的步骤是:

  • Check when the editor is focused.检查编辑器何时聚焦。
  • When focused, check if a picture has previously been clicked and if a selected text is available (the alt of the image).聚焦后,检查之前是否单击过图片以及selected文本是否可用(图像的alt )。
  • If yes, insert the selected text (the alt of the image) at the current position.如果是,则在当前位置插入selected文本(图像的alt )。

The JavaScript code associated to these steps would looks like:与这些步骤相关的 JavaScript 代码如下所示:

// Listen to the editor focus events.
editor.on('focus', function () {
  // Only insert if a value has been previously selected.
  if (selected.length > 0) {
    // Fetch the current CodeMirror document.
    var doc = editor.getDoc();

    // Insert the text at the cursor position.
    doc.replaceSelection(selected);

    // Clear the selection so it isn't copied repeatedly.
    selected = '';
  }
});

You can check a working example on this JSFiddle .您可以在此 JSFiddle上查看一个工作示例。

简而言之,此代码将用文本替换代码镜像当前选择(或没有任何选择时的当前光标位置):

codemirror.doc.replaceSelection('text to replace');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM