ロゴ
HOME > jQuery・Javascript > ブラウザで使うWYSIWYGエディターを作るときのcreateRangeとかselectionなんかの処理

ブラウザで使うWYSIWYGエディターを作るときのcreateRangeとかselectionなんかの処理

2015年03月05日

WordPressでこうして記事を書く時に、文字色を変えたりできるエディターを使いますが、簡単なものなら自作する事も可能です。また、多くの方が有償・無償でWYSIWYGエディターリッチテキストエディターを作成・公開しています。

TinyMCEが有名でしょうか、ただ、商用だとライセンスの問題が出てきます。MITライセンスのものも有りますが、一番欲しい画像アップロード機能が無くがっくりくることも。

お客さんってたいがい、記事を書くのと画像をアップロード出来る、これを求めますので、ここは抑えておきたいポイントですよね。あと機能過多で使わないものが多く、削るのが面倒です。

で、人のを借りるのも癪だし高いライセンス料を払いたくないですし、どうせなら機能を限定して導入し易いものを作ればオープンソースにも導入し易いだろうなぁと思い、テスト用のとってもちゃちぃ(←方言?)ものを作ってみました。

サンプル

一応はIE8以上対応って事で書いています。そう、IEくん、君だよ君

この、古参大手シェア大なブラウザさえ無ければ、どれだけのWEBデザイナーさんの労力が軽くなる事か。新しいバージョン出す度に開発者の足を引っ張るIEくん、ほんとどうにかなりませんでしょうか。

さて、WYSIWYGエディターの話しに戻します。

そもそもWYSIWYGエディターってどういう仕組なのか

iframeってご存知でしょうか?最近は使う機会が減りましたが、iframeの中に別なページを表示出来るので、サイドバーナビゲーションなんかによく使われていたHTMLタグです。で、このiframのデザインモードをONにする事で編集出来るようになります。

デザインモードをONにする
    /*
     * iframのデザインモードをONにする
     */
      doc = document.getElementById('iFrameName').contentDocument;
      doc.designMode = "On";

これだけで編集する事が出来るようになります。

で、ボタンを作って押したときに下のようなコマンドを実行すると、文字を太くしたり出来ます。

execCommand('bold', false, null);

このコマンドを実行する為のトリガーにbutton以外は使わない方が吉。画像とかAタグで格好良く決めたい!と思っても、IEだと別の場所をクリックしたりするだけで、選択した文字のフォーカスが外れてしまうのです(selectは大丈夫そう)

なので、ボタンを押すだけで実行出来る、太字とか斜体とか取り消し線などの処理はボタンで配置し、背景に画像なんかを指定して並べると良いと思います。

IEでフォーカスが外れる!ほんと要らないコ・・・・

さて、ボタン一発で済まない処理、例えば選択した文字にURLを指定してリンクにしたいといったケースです。これは文字を選択した後にURLを入力しようとすると、IEは選択した文字のフォーカスが外れてしまい、どこにAタグを指定すれば良いのか解らなくなってしまいます。

なので、フォーカスした位置を記憶して、処理を終えたらフォーカスを戻すって処理をする事になります。

何か操作したときにフォーカスの位置を記録する

これをリンク挿入ボタンを押したときに実装します。それぞれ、変数に代入しておきます。

  var set_sel   = null;
  var set_range = null;

      function getRange(){
        var sel = win.getSelection ? win.getSelection() : doc.selection;
        if(!sel || sel.rangeCount === 0) return;
        var rng = (sel.rangeCount > 0) ? sel.getRangeAt(0) : sel.createRange();
        
      //selectionとrangeを記録
        set_range = rng;
        set_sel   = sel;
      }
マウスやキーボードの操作があれば、フォーカスを戻す

とりあえずテキストフォームに入力したり、キーボード操作をしたら記憶したフォーカスが無いかを確認し、あればフォーカスを戻す処理を実行します。

$("body").on("mousedown keypress focus blur keyup", addEvent);

      function addEvent(){
        if(set_sel === null && set_range === null) return;
          if(window.getSelection) {
            set_sel.removeAllRanges();
            set_sel.addRange(set_range);
          } else {
            set_range.select();
          }
      }
コマンド実行後などにフォーカスを削除する

処理を終えたらフォーカスしておく必要は無いので、変数を初期化します。

    /*
     * リンクする
     */
      $(document).on('click','#urllink',function(){
        if( $("#link").val() ){
          doc.execCommand('createlink', false, $("#link").val());
          $("#link").val('');
        }
        set_sel = null;
        set_range = null;
      });

 

なんて事をやれば、IEさんでもいけます。Widows10でIEはSpartanという名称に変わるそうですが、レンダリングエンジンは変わらないそうです・・・バージョンアップごとにWEB屋の頭を悩ませるブラウザですので、また何か変更が有りそうで怖いですね。

とりあえず自分用の予定ですが、WYSIWYGエディターを暇なときに作ってみようかと思います。