シンプルで今後使ってみたいBlock Styleエディター Editor.js
本文書で今回紹介するのはNote, Medium, WordPressのGutenbergのようなブロックスタイルのエディターのEditor.jsです。Rich Text Editorとしてシンプルで使いやすそうだったのでどのように設定を行うのか確認しました。現在も更新が行われており、2024年9月現在のバージョンはv2.30.5です。
動作確認はmacOSで行っていますがcdnで利用することができるため動作確認を簡単に行うことができます。
目次
Ediror.jsとは
Editor.jsのページにはFree block-style editorと記述されている通りブロックスタイルのエディターです。
Editor.jsは主に下記の3つの特徴的な機能を持っています。
一つ目の特徴はブロックスタイルエディターということで見出し(Heading)、段落(Paragraph)単位にブロックが割り振られ、ブロック毎に編集を行い、ブロッグ毎に位置の入れ替えを行うことができます。Note, Medium, WordPressのGutenbergでも利用されている方法なのでブロックスタイルエディターということを意識せず利用している人も多いかと思います。
二つ目の特徴はブロックに記述した内容をJSONオブジェクトして取り出すことができます。JSONオブジェクトとして取り出せるので他のアプリケーションにも簡単に渡すことできます。JSONの構造さえわかればJSONオブジェクトの中身をHTMLページとして表示させることが可能です。
三つ目の特徴は見出し(Heading)や段落(Paragraph)などの既存で準備されているブロックだけではなく独自のブロックを作成しプラグインとして追加することができます。プラグインとして簡単に追加できるような仕組みになっているのでカスタマイズを行うことが可能です。
cdnを使って動かしてみよう
Editor.jsの動作確認はcdnを利用して行うことができます。cdnのURLは下記の通りです。
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
Editor.jsを利用するためには要素にidを設定してEditorJSをインスタンス化する際にholderプロパティに要素に設定したidの値を指定します。ここではidの値がeditorjsを持つdiv要素設定しています。後ほど利用するボタンも追加しています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Editor.js</title>
</head>
<body>
<h1>Editor.jsを理解する</h1>
<div id="editorjs"></div>
<button>記事を保存する</button>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
<script>
const editorJS = new EditorJS({
holder: "editorjs",
});
</script>
</body>
</html>
ブラウザで確認するとh1タグで設定した文字列とボタン以外は何も表示されていません。
ブラウザをクリックするとブラウザ上にプラス(+)のアイコンが表示されることがわかります。これがブロックでその中に文字を入力することができます。
文字を入力してみよう
プラスのアイコンの右側から文字を入力することが可能です。
入力後に左側の四角をクリックするとMove UpとMove DownとDeleteのメニューが表示されます。
Deleteをクリックすると”Click to delete”と確認の文字に変わりので”Click to delete”をクリックするとブロックが削除されます。
Move UpとMove Downは複数のブロックがある場合にブロッグを上下方向に移動させることができます。
文字を入力後にEnterを押すと新たにブロックが作成されます。下記では4つの段落(Paragraph)つまり4つのブロックで構成されています。このようにブロック単位で段落(Paragraph)を追加していくことができます。ブロックはその場所に固定されているわけではなくブロック単位で移動することができます。
入力した内容を取り出そう
ブラウザ上に文章が入力できることはわかりました。次は入力した文章を一括で取得する方法を確認していきます。
index.htmlファイルでは”記事を保存する”ボタンを設定しているのでボタンをクリックすると入力した内容が表示できるようにボタンにクリックイベントを設定します。入力したデータを取得するためにはsaveメソッドを利用します。
const btn = document.querySelector("button");
btn.addEventListener("click", function () {
editorJS
.save()
.then((outputData) => {
console.log("input Data ", outputData);
})
.catch((error) => {
console.log("failed: ", error);
});
});
ブロックに文章を入力後ブラウザ上にある”記事を保存する”ボタンをクリックするとデベロッパーツールのコンソールに入力した内容が表示されます。
time, blocks, versionを確認することができます。blocksの中の配列を展開すると配列の中に入力した文字列がtextとして保存されていることがわかります。デフォルトの状態では入力した内容とid, typeがblocksの配列の中に保存されます。
入力した内容がsaveメソッドで取得でき、どのような形式で取得できるのか確認することができました。入力した内容の取得方法がわかりましたが、取得した内容を再度表示したい場合の方法が今のところわかりません。次はその方法を確認します。
保存した内容を表示させたい場合は?
ページを開いた時にこれまで入力した内容を表示させたい場合はdataプロパティを利用します。
本文書ではデータを保存する仕組みがないので、入力して取り出したデータを下記のようにdataプロパティに入れることで再度Editor.js上に表示させ、編集することが可能になります。
const editorJS = new EditorJS({
holder: 'editorjs',
data: {
blocks: [
{
type: 'paragraph',
data: {
text: 'ここに文字を入力することができます.',
},
},
{
type: 'paragraph',
data: {
text: 'Enterを押すと新しいブロックが作成されます。',
},
},
{
type: 'paragraph',
data: {
text: 'Enterを押すと新しいブロックが作成されます。',
},
},
],
},
});
下記のように取り出したJSONの内容を使うことで再度その内容を表示させることができます。
localStorageの利用
dataプロパティを利用することで初期値を設定することができることがわかったのでブラウザをリロードしても入力した値を保持するためにlcoalStorageを利用して設定を行ってみます。
<script>
const getContent = () => {
const savedContent = localStorage.getItem('content');
if (savedContent) {
return JSON.parse(savedContent);
}
return null;
};
const loadContent = getContent();
const editorJS = new EditorJS({
holder: 'editorjs',
data: loadContent,
});
const btn = document.querySelector('button');
btn.addEventListener('click', function () {
editorJS
.save()
.then((outputData) => {
localStorage.setItem('content', JSON.stringify(outputData));
})
.catch((error) => {
console.log('failed: ', error);
});
});
</script>
Editor.jsには初期化するときに実行されるonReadyや変更が行われたら実行されるonChangeコールバックもあります。onReadyプロパティで関数を利用してlocalStorageに保存したデータを取得して表示することができます。
const getContent = () => {
const savedContent = localStorage.getItem('content');
if (savedContent) {
return JSON.parse(savedContent);
}
return null;
};
const editorJS = new EditorJS({
holder: 'editorjs',
onReady: () => {
const loadContent = getContent();
if (loadContent) {
editorJS.render(loadContent);
}
},
});
ヘッダータグを設定したい場合は
ここまで入力した内容はすべて段落(Paragraph)でしたHeadingタグ(見出しタグ)を利用したい場合はどのように行うのか確認します。
Editor.jsのデフォルトの状態ではブロックには段落(Paragraph)のみ利用することができます。ヘッダータグなど他のものを利用したい場合はプラグインで追加を行う必要があります。通常はimportを利用しますがここではcdnを利用して追加を行います。
ヘッダーブロックのプラグインのcdnを下記となります。
<script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script>
追加したプラグインの設定は下記のように行います。levelsを設定することでヘッダータグのレベルを選択することができます。デフォルトのレベルも設定することできlevel3に設定しています。
const editorJS = new EditorJS({
holder: 'editorjs',
onReady: () => {
const loadContent = getContent();
if (loadContent) {
editorJS.render(loadContent);
}
},
tools: {
header: {
class: Header,
config: {
levels: [2, 3, 4],
defaultLevel: 3,
},
},
},
});
設定後プラスのアイコンをクリックするとプルダウンメニューによりTextとHeadingを選択することができます。Headingを選択するとヘッダータグとなり文字を入力するとデフォルトのh3として入力することができます。
h3タグなので段落(paragraph)と比較して文字が大きく太く表示されます。デベロッパーツールの要素を見るとh3タグで表示されていることが確認できます。
左側の四角をクリックするとhタグを変更することも可能です。
saveメソッドで入力した内容を確認すると入力した内容の中にはh2,h3などのタグが含まれることはなく、levelプロパティが一緒に保存され、Typeはheaderになっていることが確認できます。
Listタグの追加
ListタグもHeaderタグと同様にプラグインを追加する必要があります。
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/list@latest"></script>
<script>
//略
const editorJS = new EditorJS({
holder: 'editorjs',
onReady: () => {
const loadContent = getContent();
if (loadContent) {
editorJS.render(loadContent);
}
},
tools: {
header: {
class: Header,
config: {
levels: [2, 3, 4],
defaultLevel: 3,
},
},
list: {
class: List,
},
},
});
追加後プラスのアイコンをクリックするとリストのアイコンが追加されてリストで入力することがわかります。
また左側の四角のアイコンをクリックすると番号あり(Unordered)となし(Ordered)のリストを選択することができます。
入力した内容を確認するとtextプロパティからitemsプロパティに変わり、styleプロパティが追加されordered、typeはListと表示されます。
文字の装飾の変更
太字やイタリック表示への変更はキーボードショートカットキーでも行うことができますが入力した文字列を選択するとメニューが表示されます。Bを選択すると太字となります。
リンクのアイコンを選択した場合にはAdd a Linkでリンク先を設定することができます。macOSで利用しているのでキーボードショートカットキーはCommand+Kであることがわかります。
入力した内容を確認するとtextに保存されている文字列にbタグやaタグが設定されていることが確認できます。
configの設定
paddingの設定
デフォルトでは入力する領域とボタンまでの間にpadding:300pxが設定されているので入力する情報が少ない場合は離れすぎていると感じることがあります。
minHeightを設定することでpaddingの大きさを変更することができます。
const editorJS = new EditorJS({
holder: "editorjs",
minHeight: 50,
minHeightを設定するとpaddingの大きさが小さくなったことを確認することができます。
placeholderを設定
何も入力が行われていない場合に画面には何も表示されないのでplaceholderの設定を行うことでユーザが何を入れるか判断する材料になります。しかしデフォルトでは最初のブロックは段落(paragraph)なのでdataを使って空のヘッダーブロックを入れます。placeholderはconfigの中で設定を行います。
const editorJS = new EditorJS({
holder: "editorjs",
minHeight: 50,
tools: {
header: {
class: Header,
config: {
placeholder: "見出しを入力してください",
levels: [2, 3, 4],
defaultLevel: 2,
},
},
list: {
class: List,
},
},
data: {
blocks: [
{
type: "header",
data: {
text: "",
level: 2,
},
},
],
},
});
下記のようにplaceholderを設定するとpタグにplaceholderが表示されます。
const editorJS = new EditorJS({
holder: 'editorjs',
placeholder: 'ここから入力してください',
画像用のプラグインや自作のプラグインを追加することも可能なのでさらに動作確認が必要ですがEditor.jsがどのようなものかはしっかり理解することできました。
[付録]パッケージをインストールして動作確認
CDNを利用して動作確認を行いましたがNode環境でパッケージをインストールするることで利用することも可能です。npmコマンドでeditorJsをインストールするためにはNodeのインストールが必須となります。node -Vコマンドを実行してNodeのバージョンが表示されることを確認してください。表示されない場合はNodeのインストールを行なってください。
% node -v
v14.7.0
Nodeの確認ができたら任意の名前のフォルダを作成してnpm init -yコマンドを実行してください。package.jsonファイルが作成されます。
次にwebpackのインストールを行います。
% npm install --save-dev webpack webpack-cli
次にeditorjsのインストールを行います。
% npm i @editorjs/editorjs --save
srcフォルダを作成してその中にindex.jsファイルを作成してください。
import EditorJS from '@editorjs/editorjs';
const editor = new EditorJS({
/**
* Id of Element that should contain the Editor
*/
holder: 'editorjs',
});
package.jsonファイルを開いてwebpackを実行するための設定を行います。scriptプロパティに以下の設定を行なってください。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
npm run devを実行するとdistフォルダにmain.jsファイルが作成されるので、index.htmlファイルからscriptタグでそのファイルを指定します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module" src="./dist/main.js"></script>
<title>Document</title>
</head>
<body>
<h1>Editor.jsを理解する</h1>
<div id="editorjs"></div>
<button>記事を保存する</button>
</body>
</html>
下記の画面が表示されれば環境の構築は完了です。