Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
139
Help us understand the problem. What is going on with this article?
@kenzooooo

ブログ記事等のエディタを実装する際はCKEditor!さらに便利でカッコよく使い易く!サンプルソースあり

More than 3 years have passed since last update.

簡単なJavaScriptの実装でエディタが作成できる!

スクリーンショット 2016-02-12 13.06.24.png

CKEditorとは

CKEditorを読み込んだ初期表示はこんな感じです。wordpressでブログ記事を書いたことがある方なら、おなじみのエディタだと思われます。

スクリーンショット 2016-02-08 21.24.17.png

このCKEditor、初期状態でもかなり高機能です。例えば、下の画像のようにソースコード表示ができ、ソースコードを編集することができます。

スクリーンショット-2016-02-08-21.24.38.png

また、ソースコード表示ではなくHTMLの表示結果を編集することもできます。(HTMLを知らない人でも編集可能)
下の画像では、見出しを選択して打ち消し線ボタンをクリックし、見出しに打ち消し線を付けています。
スクリーンショット-2016-02-08-21.25.17.png

CKEditorの実装

CKEditor( CDN )を読み込み、scriptタグ内でdivにCKEditorをセットしています。
たったこれだけの記述で、エディタを実装することができます。また、CKEditorはJQueryを必要としません。

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
</head>
<body>
  <div id="editor"></div>
  <script src="https://cdn.ckeditor.com/4.5.6/standard/ckeditor.js"></script>
  <script>
    // エディタへの設定を適用する
    CKEDITOR.replace('editor', {
      uiColor: '#EEEEEE',
      height: 400,
    });
  </script>
</body>
</html>

ただし、今回はこのCKEditorをさらにかっこよくし、さらに便利で使い易い状態にしていきます。最終的に作成するのは下の画像の状態になります。

スクリーンショット 2016-02-12 12.16.02.png

見た目をカッコよく

まずはCKEditorの見た目をカッコよくします。下の画像のように、エディタ自体の色を変更し、ツールバーを下側に来るようにします。また、その他の細かい設定もサンプルソースと共に解説いたします。ブログ等の記事は、文字を記述していくにつれカーソル位置が下に下がっていくので、個人的にはツールバーは下部に配置したほうが使いやすいと思っています。

スクリーンショット 2016-02-08 21.54.31.png

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">

</head>
<body>
  <div id="editor"></div>
  <script src="https://cdn.ckeditor.com/4.5.6/standard/ckeditor.js"></script>
  <script>
    // エディタへの設定を適用する
    CKEDITOR.replace('editor', {
      uiColor: '#EEEEEE',
      height: 400,
      // エディタ内に適用するCSS
      contentsCss: [
        "./css/sample.css",
      ],
      // スペルチェック機能OFF
      scayt_autoStartup: false,
      // Enterを押した際に改行タグを挿入
      enterMode: CKEDITOR.ENTER_BR,
      // Shift+Enterを押した際に段落タグを挿入
      shiftEnterMode: CKEDITOR.ENTER_P,
      // idやclassを指定可能にする
      allowedContent: true,
      // ツールバーを下にする
      toolbarLocation: 'bottom',
      // preコード挿入時
      format_pre: { element: 'pre', attributes: { 'class': 'code' } },
      // タグのパンくずリストを削除
      removePlugins: 'elementspath',
      // webからコピペした際でもプレーンテキストを貼り付けるようにする
      forcePasteAsPlainText: true,
      // 自動で空白を挿入しないようにする
      fillEmptyBlocks: false,
      // タブの入力を無効にする
      tabSpaces: 0,
    });
  </script>
</body>
</html>

contentsCssで、エディタ内で使用するCSSを適用できます。sample.cssはこの記事の最後に掲載させていただきます。

配置するボタンのカスタマイズ

CKEditorに配置されているボタンは初期状態だとかなり種類が多く、ユーザーからすると逆に使い辛い場合があります。また、初期状態には用意されていないボタンを独自に作成することも可能です。
下の画像のように、配置するボタンの種類や内容をカスタマイズしていきます。細かい設定などはサンプルソースと共に解説します。
また、オプションの指定などの詳細はhttp://docs.ckeditor.com/#!/api/CKEDITOR.dom.comment こちらで確認できます。(ドキュメントが若干見づらくて英語...)

ツールバーへの配置設定

  // エディタへの設定を適用する
  CKEDITOR.replace('editor', {
    // ツールバーに配置するボタンの種類を指定
    toolbar: [
      ["Source"],                                    // ソースコード表示切り替え
      ["Link", "Image", "Table", "HorizontalRule"],  // リンク、画像配置、テーブル、線
      ["Bold", "Underline", "Strike"],               // 太字、打ち消し線
      ["code"],                                      // 強調表示
      ["Recommend"],                                 // おすすめ
    ],
  });

codeと、Recommend以外はデフォルトで使用できるボタンになります。codeと、Recommendの内容についてはこれから作成していきます。

ボタンのカスタマイズ(おすすめボタン)

  // おすすめボタンを押した際に挿入するhtmlコード
  var recommend = '<div class="highlight"><h2 class="recommend">タイトル</h2><ol type="1"><li>項目1</li></ol></div>';

  // エディタのelement
  var editor = CKEDITOR.instances.editor;
  // エディタのプラグインが呼び出される際のcallback
  editor.on('pluginsLoaded', function(ev){
    // 各ボタンの定義
    this.ui.addButton('Recommend', {
      label: 'recommend', command: 'recommend', icon: 'images/icon_recommend.png'
    });
    this.addCommand('recommend', {
      exec: function(editor) {
        editor.insertHtml(recommend);
      }
    });
  });

まず、 var recommend = ... でボタン押下時にエディタ内に挿入するコードを定義します。
その次に、CKEditorの初期化時に呼ばれるcallback関数に、ボタンの定義を記述します。

this.ui.addButton ... でおすすめボタンの見た目の設定を行います。iconや、どのコマンドを実行するかを指定します。iconの画像はお好きなものを使用してください。

this.addCommand ... でボタン押下時の処理を記述します。上記コードの場合は、insertHTML関数でhtmlコードをエディタ内に挿入しているだけです。

おすすめボタンが追加されました。
スクリーンショット-2016-02-12-11.48.42.png

ボタンのカスタマイズ(強調表示ボタン)

続いて、強調表示ボタンを追加します。強調表示ボタンは、エディタ上で選択した文字列の範囲を強調します。さきほど追加したおすすめボタンと追記する内容についてはほぼ同じです。

  // 強調表示
  var code = '<code>強調</code>';

  // エディタのelement
  var editor = CKEDITOR.instances.editor;
  // エディタのプラグインが呼び出される際のcallback
  editor.on('pluginsLoaded', function(ev){
    // 各ボタンの定義
    this.ui.addButton('code', {
      label: 'code', command: 'code', icon: 'images/code.png'
    });
    this.addCommand('code', {
      exec: function(editor) {
        editor.insertHtml(replace_tag_inner(code, "強調"));
      }
    });
  });

this.addCommand... おすすめボタン作成時は、単純にinsertHTMLを行っていましたが、今回は選択範囲を強調表示させたいので、エディタ内で選択されている範囲を取得し、範囲内の文字列を強調表示に置き換えた上でinsertHTMLを行わなければいけません。そこで、replace_tag_inner()という関数を作成します。

  // タグ内にエディタで選択中の文字列を挿入する
  function replace_tag_inner(tag, str) {
    var result = tag;
    var selected_str = editor.getSelection();
    // エディタ内で選択中の文字列が存在する場合
    if (selected_str && selected_str.getNative() != '') {
      result = result.replace(str, selected_str.getNative());
    }
    return result;
  }

上記コードは、エディタ内での選択範囲をeditor.getSelection()で取得し、強調表示用のタグに置き換えています。

強調表示ボタンが追加されました。
スクリーンショット-2016-02-12-12.01.57.png

このように、ボタンを追加していくことでより便利な機能を追加することができます。

まとめ & サンプル

以上が今回ご紹介するカスタマイズ内容になります。
下記のソースが今回の内容をまとめたものです。

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">

</head>
<body>
  <div id="editor"></div>
  <script src="https://cdn.ckeditor.com/4.5.6/standard/ckeditor.js"></script>
  <script>
    // エディタへの設定を適用する
    CKEDITOR.replace('editor', {
      uiColor: '#EEEEEE',
      height: 400,
      // エディタ内で使用するCSS
      contentsCss: [
        "./css/sample.css",
      ],
      toolbar: [
        ["Source"],
        ["Link", "Image", "Table", "HorizontalRule"],
        ["Bold", "Underline", "Strike"],
        ["FontSize", "TextColor"],
        ["code"],
        ["Recommend"],
      ],
      // スペルチェック機能OFF
      scayt_autoStartup: false,
      // Enterを押した際に改行タグを挿入
      enterMode: CKEDITOR.ENTER_BR,
      // Shift+Enterを押した際に段落タグを挿入
      shiftEnterMode: CKEDITOR.ENTER_P,
      // idやclassを指定可能にする
      allowedContent: true,
      // ツールバーを下にする
      toolbarLocation: 'bottom',
      // preコード挿入時
      format_pre: { element: 'pre', attributes: { 'class': 'code' } },
      // タグのパンくずリストを削除
      removePlugins: 'elementspath',
      // webからコピペした際でもプレーンテキストを貼り付けるようにする
      forcePasteAsPlainText: true,
      // 自動で空白を挿入しないようにする
      fillEmptyBlocks: false,
      // タブの入力を無効にする
      tabSpaces: 0,
    });

    // おすすめボタンを押した際に挿入するhtmlコード
    var recommend = '<div class="highlight"><h2 class="recommend">タイトル</h2><ol type="1"><li>項目1</li></ol></div>';
    // 強調する文字
    var code = '<code>強調</code>';
    // エディタのelement
    var editor = CKEDITOR.instances.editor;

    // エディタのプラグインが呼び出される際のcallback
    editor.on('pluginsLoaded', function(ev){
      // 各ボタンの定義
      this.ui.addButton('Recommend', {
        label: 'recommend', command: 'recommend', icon: 'images/recommend.png'
      });
      this.ui.addButton('code', {
        label: 'code', command: 'code', icon: 'images/code.png'
      });
      this.addCommand('recommend', {
        exec: function(editor) {
          editor.insertHtml(recommend);
        }
      });
      this.addCommand('code', {
        exec: function(editor) {
          editor.insertHtml(replace_tag_inner(code, "強調"));
        }
      });
    });

    // タグ内にエディタで選択中の文字列を挿入する
    function replace_tag_inner(tag, str) {
      var result = tag;
      var selected_str = editor.getSelection();
      // エディタ内で選択中の文字列が存在する場合
      if (selected_str && selected_str.getNative() != '') {
        result = result.replace(str, selected_str.getNative());
      }
      return result;
    }
  </script>
</body>
</html>
sample.css
.highlight {
    width: auto;
    background-color: #f7f3f2;
    border-radius: 3px;
    padding: 15px;
    line-height: 1.15em;
    word-wrap: break-word;
    margin-bottom: 10px
}

.highlight h2 {
    color: #000;
    font-size: 16px;
    font-weight: bold;
    margin: 0;
    margin-bottom: 15px;
    line-height: 1.5em;
    padding: 10px;
    padding-left: 0
}

.highlight h2.recommend:before {
    content: "オススメ";
    color: #fff;
    font-size: 12px;
    background-color: #ff9900;
    border-radius: 50%;
    padding: 20px 5px;
    margin-right: 10px
}

code {
    padding: 2px 4px;
    color: #d14;
    white-space: nowrap;
    background-color: #f7f7f9;
    border: 1px solid #e1e1e8;
    font-size: 1em;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
    font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
}

以上になります。

139
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
usestrict
集客・収益化を加速させるCMS「メディプロ」の開発/運営を行っております。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
139
Help us understand the problem. What is going on with this article?