LoginSignup
6
5

More than 1 year has passed since last update.

Monaco Editorで、埋め込みエディタのコード変更イベントをリッスンする方法

Last updated at Posted at 2022-06-01

VS codeのソースをもとにウェブブラウザー上で動くよう作成されたMonaco Editor。自身のウェブサイトにエディタを埋め込むことで、エンジニア向けサービス等はぐっとUI/UXが改善されます。

今回は、Monaco Editorで埋め込まれたエディタに対して、ユーザーがコードを書き込む等の変更を行ったイベントをリッスンする方法についてまとめます。Monaco Editorに関する基本的な使い方が分かっている前提で説明を進めるので、場合によってはMonaco Editorの基本的な使い方を事前に読んでいただくとよいかと思います。

前提

chrome(バージョン: 101.0.4951.67)
Monaco Editor version 0.33.0.

説明のために使用するサンプルコード

以下のようなサンプルコードのサイトを使用します。

サンプルコード.html
<!DOCTYPE html>
<html>
  <head>
    <title>browser-amd-editor</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  </head>
  <body>
    <h2>Monaco Editor Sample</h2>
    <div
      id="container"
      style="width: 800px; height: 600px; border: 1px solid grey;"
    ></div>
    <script src="./node_modules/monaco-editor/min/vs/loader.js"></script>
    <script>
      require.config({ paths: { vs: "./node_modules/monaco-editor/min/vs" } });

      require(["vs/editor/editor.main"], function () {
        var editor = monaco.editor.create(
          document.getElementById("container"),
          {
            value: [
              "function x() {",
              '\tconsole.log("Hello world!");',
              "}",
            ].join("\n"),
            language: "javascript",
          }
        );
      });
    </script>
  </body>
</html>

サイトの見た目は以下のようにシンプルです。
image.png

今回リッスンしようとしているイベントは、例えば、以下の画像のように空行が追加する等です。
image.png

テキストエディタの変更をリッスンするために必要なイベントが何なのかは、公式ドキュメントやPlay Groundに明記されておらず、Monaco Editorに関する情報は日本語でほとんど存在しないです。自分なりにいろんなコードを試すか、海外サイト(例えばStack Overflow等)を見た方が近道だったりします。

テキストエディタの変更をリッスンするために必要なコード

テキストエディタの変更をリッスンするために必要なコードは以下のように、getModelメソッドとonDidChangeContentメソッドを用いたものになります。

editor.getModel().onDidChangeContent((event) => {
  console.log(editor.getValue());
  console.log(event);
});

HTMLファイル全体はこんな感じです。

テキストエディタの変更をリッスンできるHTML.html
<!DOCTYPE html>
<html>
  <head>
    <title>browser-amd-editor</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  </head>
  <body>
    <h2>Monaco Editor Sample</h2>
    <div
      id="container"
      style="width: 800px; height: 600px; border: 1px solid grey;"
    ></div>

    <!-- OR ANY OTHER AMD LOADER HERE INSTEAD OF loader.js -->
    <script src="./node_modules/monaco-editor/min/vs/loader.js"></script>
    <script>
      require.config({ paths: { vs: "./node_modules/monaco-editor/min/vs" } });

      require(["vs/editor/editor.main"], function () {
        var editor = monaco.editor.create(
          document.getElementById("container"),
          {
            value: [
              "function x() {",
              '\tconsole.log("Hello world!");',
              "}",
            ].join("\n"),
            language: "javascript",
          }
        );

        editor.getModel().onDidChangeContent((event) => {
          console.log(editor.getValue());
          console.log(event);
        });
      });
    </script>
  </body>
</html>

これで、エディタ内に変更があるたびに、特定の処理を実行できます。
今回は、

console.log(editor.getValue());
console.log(event);

との処理を書いています。

それぞれどのようにコンソールに出力されているか見てみましょう。

例えば、Enterを押して空行を入れたとします。
image.png

すると、イベントがリッスンされて、editor.getValue()がコンソールに出力されます。
image.png
画像. console.log(editor.getValue());の結果

また、console.log(event);の方では、以下のような連想配列(Hash, Object)が出力がされています。
image.png
changesというkeyの値である配列の0番目に格納されている連想配列のtextというkeyの場所に、今回の変更'\n\t'(改行とタブを行ったことになっている)が書かれています。

console.log(event);については、改行だと分かりにくいかと思いますので、aと記載した場合のコンソールも合わせて表示します。
image.png
image.png

getModelメソッドを詳しく解説

getModelについてはMonaco Editor公式ドキュメントのおそらくここが該当します。「おそらく」とつけたのは、パラメーター(引数)がなくて実行された場合の記述がないためです。

Interface ITextModelオブジェクトを返します。

onDidChangeContentメソッドを詳しく解説

onDidChangeContentについては、Monaco Editor公式ドキュメントにて、以下のように記述されています。

onDidChangeContent
onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable
An event emitted when the contents of the model have changed.

Interface ITextModelオブジェクト(=model)に変化があった場合に、IModelContentChangedEventイベントをリッスンします。

参考にした記事

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5