简体   繁体   English

如何使用 Javascript 和 Ace.JS 将代码单元添加到 HTML 页面?

[英]How to add code cells to HTML page with Javascript and Ace.JS?

Is it possible to create several text editor cells within a single page?是否可以在单个页面中创建多个文本编辑器单元格? My desired outcome is to have a button that when clicked allows the user to add new cells of code, where the user can write and later run.我想要的结果是有一个按钮,当单击该按钮时,用户可以添加新的代码单元格,用户可以在其中编写并稍后运行。 Similar to Jupyter notebook.类似于 Jupyter 笔记本。 The editor itself is imported from the ace.js library.编辑器本身是从ace.js库中导入的。

For that, I think I need some function add_editor(parent_div) that adds a new text editor to a div that is given as a parameter.为此,我认为我需要一些 function add_editor(parent_div) 将新的文本编辑器添加到作为参数给出的 div 中。 ( Which I have failed to implement ) (我未能实施)

My initial thoughts are perhaps to create a shared class for all of the editors and append it to the father div with jQuery, but when I tried using a class instead of an id for the design,the editor won't load. My initial thoughts are perhaps to create a shared class for all of the editors and append it to the father div with jQuery, but when I tried using a class instead of an id for the design,the editor won't load. I'm not so good with handling with the DOM (especially without React), so even if the solution seems obvious to you, it might not to me.我不太擅长处理 DOM(尤其是没有 React),所以即使解决方案对你来说很明显,对我来说也可能不是。

This is last working version of the code that I have so far这是迄今为止我拥有的代码的最后一个工作版本

<html lang="en">
   <head>
      <title>ACE in Action</title>
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
      <!-- Define the editor's CSS !-->
      <style type="text/css" media="screen">
         #editor {
         width: 100%;
         height: 100%;
         }
      </style>
   </head>
   <body>
      <div class="row">
         <!-- a row of two columns: the first will contain the text editors, the second is irrelevant !-->
         <div class="col-9" style="height:200px;">
            <div class="container" style="">
               <div id="editor">
                  <!-- the div containing the code, has the id "editor" !-->
                  def print_something():
                  print(a)
               </div>
            </div>
         </div>
         <div class="col-3">
            empty column
         </div>
      </div>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.5/ace.js" type="text/javascript" charset="utf-8"></script>
      <script>
         function configure_editor(){
             var editor = ace.edit("editor");
             editor.setTheme("ace/theme/monokai");
             editor.session.setMode("ace/mode/python");
             editor.getSession().setUseWrapMode(true);
             editor.setShowPrintMargin(false);
         }
         configure_editor()
         
      </script>
   </body>
</html>

Help will be much appreciated!帮助将不胜感激!

Edit: I need to solve this in Javascript or Jquery, without React.编辑:我需要在 Javascript 或 Jquery 中解决此问题,无需 React。

I think I have found somewhat of a solution on my own with jQuery, even though it seems messy.我想我已经用 jQuery 自己找到了一些解决方案,尽管它看起来很乱。 Each time a new editor will be added with increasing ids, ie: "editor0", "editor1", "editor2", and so on.每次都会添加一个新的编辑器,其 id 会增加,即:“editor0”、“editor1”、“editor2”等。

Here is the full code这是完整的代码

<html lang="en">
   <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
      <title>ACE in Action</title>
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
      <!-- Define the editor's CSS !-->
   </head>
   <body>
      <div class="row">
         <!-- a row of two columns: the first will contain the text editors, the second is irrelevant !-->
         <div class="col-9" style="height:200px;">
            <div id="editors_container">
            </div>
         </div>
         <div class="col-3">
            <button id="add_editor">Add a new editor</button>
         </div>
      </div>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.5/ace.js" type="text/javascript" charset="utf-8"></script>
      <script>
          existing_editors = [];
          $(document).ready(function(){
            $("#add_editor").click(function(){
                console.log("reached here!")
                let editor_id = "editor"+existing_editors.length;
                $newDiv = $("<div id="+editor_id+" style=width:100%;height:100%>"+"</div>");
                $("#editors_container").append($newDiv);
                let editor = ace.edit(editor_id);
                editor.setTheme("ace/theme/monokai");
                editor.session.setMode("ace/mode/python");
                editor.getSession().setUseWrapMode(true);
                editor.setShowPrintMargin(false);
                existing_editors.push(editor);
            });
          });

      </script>
   </body>
</html>

A cleaner method is to assign an editor to each instance using your own structure.一种更简洁的方法是使用您自己的结构为每个实例分配一个编辑器。 With jquery:使用 jquery:

<div id="instance0"></div><div id="instance1"></div>

<script>

var instances[];

var $rootElement = $('#instance0');
newInstance($rootElement);
var $rootElement = $('#instance1');
newInstance($rootElememt);

function newInstance($rootElement){
    var instance = {};
    instance.id = $rootElement.attr('id');
    instance.$root = $rootElement;
    instance.editor = ace.edit($rootElement[0]);
    instance.editor.instance = instance;
    instances.push(instance);
}
</script>

This gives you a 1 to 1 instance to editor relationship with backpointers.这为您提供了与反向指针的 1 对 1 实例与编辑器关系。 It will save you much angst in the future.它将为您节省很多未来的焦虑。 You can just flip in sessions and keep the editors static.您可以只切换会话并保留编辑器 static。

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

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