前回カスタマイズしたSummernoteを使ってセーブ/ロード機能を持つ画面を作成してみる。
Summernoteにはエディタを操作できるAPIがあり、codeというAPIを使えばエディタの入力内容を取得/設定することができる。
取得方法
JavaScript
const contents = $('#note').summernote('code');
console.log(contents);設定方法
JavaScript
$('#note').summernote('code', '<p>Hello world</p>');このAPIを使ってローカルストレージから編集内容をセーブ/ロードする機能を追加してみた。
また、ついでにプレビュー機能も作成してみた。
動作確認環境
- jQuery(3.7.1)
- Bootstrap(5.3.5)
- Summernote(0.9.1)
実装例
Index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Summernoteカスタマイズ</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/summernote@0.9.1/dist/summernote-bs5.min.css" type="text/css" />
<link rel="stylesheet" href="./css/app.css" type="text/css" />
<link rel="stylesheet" href="./css/summernote-bs5-editor-custom.css" type="text/css" />
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/js/bootstrap.bundle.min.js" type="text/javascript"></script>
<script src="https://cdn.jsdelivr.net/npm/summernote@0.9.1/dist/summernote-bs5.min.js" type="text/javascript"></script>
<script src="https://cdn.jsdelivr.net/npm/summernote@0.9.1/dist/lang/summernote-ja-JP.min.js" type="text/javascript"></script>
<script src="./js/summernote-init.js" type="text/javascript"></script>
</head>
<body>
<div class="d-flex justify-content-center mt-3 mb-3">
<div class="d-flex gap-5">
<button id="btnLoad" class="btn btn-primary" style="min-width:120px">ロード</button>
<button id="btnSave" class="btn btn-danger" style="min-width:120px">セーブ</button>
</div>
</div>
<div class="d-flex justify-content-center mb-3">
<textarea id="note" class="summernote" style="display: none" value=""></textarea>
</div>
<!-- プレビュー領域 -->
<div class="d-flex justify-content-center">
<div class="d-flex flex-wrap" style="width:1024px">
<div class="w-100"><h2>プレビュー</h2></div>
<div id="preview" class="p-2 w-100" style="border:solid 1px;"></div>
</div>
</div>
<script type="text/javascript">
$(function () {
const storageKey = 'note-data';
let timeoutId = '';
// ローカルストレージ対応ブラウザチェック
if(typeof localStorage === 'undefined') {
alert('ブラウザがローカルストレージに対応していないため、ロード/セーブ機能は利用できません。')
$("#btnLoad").prop("disabled", true);
$("#btnSave").prop("disabled", true);
}
// Summernote初期化
$('#note').initSummernote({
height: 400,
width: 1024,
focus: true,
callbacks: {
onChange: function(contents, $editable) {
// プレビュー欄に変更を反映させる(0.5秒後)
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
$('#preview').html(contents);
}, 0.5 * 1000);
},
}
});
// ロードボタン押下時
$('#btnLoad').click(function() {
if (!localStorage.hasOwnProperty(storageKey)) {
alert('記事が保存されていません。');
return;
}
// 記事を取得しエディタにセットする
const contents = localStorage.getItem(storageKey);
if (contents)
$('#note').summernote('code', contents);
});
// セーブボタン押下時
$('#btnSave').click(function() {
try {
// summernoteで編集した記事を取得
const contents = $('#note').summernote('code');
// ローカルストレージに記事を保存
localStorage.setItem(storageKey, contents);
alert('記事を保存しました。');
} catch(err) {
console.error(err);
alert('記事の保存に失敗しました。');
}
});
});
</script>
</body>
</html>セーブ/ロード機能、プレビュー機能共に簡単に実装可能だった。
プレビュー機能はonChange毎にDOMを差し替えるのは流石に重くなりそうだったのでonChangeが走った後、0.5秒の間に再度onChangeが走らなければDOMを差し替えるように実装してみた。
実装結果
Summernoteにはcode以外にも便利なAPIが多数用意されているので公式サイト参照のこと。
コメント