Mach3.laBlog

実験室: 編集可能なTableをcontentEditableで実装してみたかった

この記事は賞味期限切れです。(更新から1年が経過しています)

この記事の情報は古くなっています。
jQuery.fn.live は既に現行バージョンで削除されています。

contentEditableは、要素をユーザ側で編集可能にする為の属性です。
ブラウザ毎でちょっとクセのある機能ですが、
これで編集可能Tableを作ったらどうなるか、という実験です。

書いてみたもの(Webkit/Firefox)

まず「myEdit」というidを持つTableを用意し、
その子要素のtdをダブルクリックした際にそのセルを編集可能にトグルし、
編集が終了したら編集不可に戻します。

※ChromeとFirefoxのみで動作確認 ※jQueryを使用

$("#myEdit td").live("dblclick",function(e){

    e.target.contentEditable = true;
    e.target.focus();

}).live("blur",function(e){

    e.target.contentEditable = false;

}).live("keydown",function(e){

    var code = e.which;
    var ctrl = (typeof e.modifiers == "undefined") ? 
    e.ctrlKey : e.modifiers & Event.CONTROL_MASK; 
    if(ctrl && code == 86){
        return false;
    }else if(e.keyCode == 13){
        e.target.blur();
        return false;
    }

}).live("contextmenu",function(e){

    return false;

});

デモを見る(JSBin)

各ブラウザのcontentEditableでの改行の仕様が安定していないので、
改行を含まない一行のみのコンテンツに制限して実装しています。
また、改行以外にも余計な要素を挿入させない為、ctrl+vは弾き、
かつコンテキストメニューを無効にしています。

なんだか、問題点いっぱいですぞ?

問題点

IE/Operaでの動作

上のスクリプトはIE/Operaでは動作しません。
というのは、どうやらtdにおけるcontentEditableが動作しない為です。
なので、何か別の要素をtdにappendして、
その要素でcontentEditableをtrueにしてやらなければなりません。

しかし、それをやるなら巷で多く使われている
input要素でスワップしてやる手法の方がよりスマートで楽です。

挙動が本当にばらばらである

各ブラウザでの挙動は本当にまちまちです。
この差異は果たしてハックで埋められるものなのか、甚だ疑問です。

データの保護が面倒

input要素ならば、「一行のテキスト」のみに制限する事は容易ですが、
contentEditableでは上記スクリプトのように面倒な処理をせねばなりません。
そもそも一行に制限しなければならない理由が「安定しないから」ですからね。

保護の為にコンテキストメニューを無効にしている点についても、
ユーザフレンドリーにする為の実装なのに、ユーザの操作を妨げるとは本末転倒。
代替で自前のコンテキストメニューを表示すれば良いですが、
果たしてそこまでしてcontentEditableでやりたいのでしょうか…

私的結論

Webサイト上でクロスブラウザな運用をするのは、
労力的な意味でも報われない感がいっぱいです。

ですが、より限定された使い方、
例えばChromeエクステンションのオプション画面等ならば
使えるのではないでしょうか。

実は、はじめからそれに使いたくて書いたんですけどね…


2010/8/23 : メニューバーからのペーストに対応出来てないことに気付く。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*