.log

ドットログ。思いついた、調べたメモ。主にフロントエンド、たまに写真とか料理とか。

contenteditableを使う

input/textarea以外の要素も編集可能にするcontenteditable属性なるものを知った。

ここは編集可能

 <div contenteditable="true"">ここは編集可能</div> 

こんな感じ。改行すると要素の大きさに合わせてエリア自体も大きくなる。
入力に合わせてテキストエリアの高さをもごもごする」記事では、テキストエリア要素を自動でリサイズしたけど、こっちのほうが使い勝手がよさそう。
(※ contenteditableで大きさが変わるときは、transitionでアニメーション出来ない)

contenteditableが持つ値

contenteditableはtrue/false/inherit/空文字の値がとれる。

true・空文字 false inherit
編集可能 編集不可 親要素の値を継承する

ここは編集できない編集可能テキスト編集可能テキスト

<div contenteditable="true""><span contenteditable="false">ここは編集できない</span>編集可能テキスト編集可能テキスト</div>

基本的には親要素の設定を引き継ぐけど、contenteditable="true"の要素の中に contenteditable="false"の要素を入れることもできる。
その時はfalseにした要素の中身は編集できないけど、falseにした要素の存在自体は編集できるので
BackSpaceでテキストを消していくと、falseにした要素はぱっと消える。


使いドコロとしては、SNSとかで使うメンションとかがいいんじゃないかと。

atsuco.a別はボーのかっこう頭めへ硝子をもっ曲だた。いやしばらくいいかげんたないというセロたた。気の毒ないましんたはましそこでゴーシュのだめ屋のうちがはやっとばかましたて、それなんか狸をなおしがっんました。
メンションの予測変換とかを上手く付けられればよさげ。

placeholderを付けたい

textarea的に使うならplaceholderを付けたい。
が、placeholderは一部のinputとtextareaにのみ有効なので、データ属性でどうにかする。

<div contenteditable="true" class="editablePlaceholder" data-placeholder="placeholderテキストが入る"></div>
.editablePlaceholder[contenteditable=true]:empty:before {
	position: absolute;
	top: 2px;
	left: 5px;
	color: #aaa;
	content: attr(data-placeholder);
}

contentプロパティの値には要素の属性値を取ることもできるので、data-placeholderという属性を持たせて擬似要素に突っ込む。
擬似クラスの:emptyを併用して、要素の中身空の場合のみ表示させる。

入力値の改行

contenteditable="true"の要素内で改行をすると、改行された文字ごとにdivもしくはpで囲まれる。
Chrome / Firefox / SafariではdivIEではpになるよう……謎。
入力されたコメントを保存する時にbrに置換するなりしないと、ユーザーのブラウザによってデータに差異が出ちゃいそう。。。

更に、最初の改行までの文字はdivもしくはpで囲まれずにただの文字列として打ち込まれるので、
複数行入力するとこんなことになる。

<div contenteditable="true">
一行目のテキストほげほげ
<div>二行目のテキストほげほげ</div>
<div>三行目のテキストほげほげ</div>
<div>四行目のテキストほげほげ</div>
</div>

これを回避するには最初から空のdivを入れておくと良さそう。


<div contenteditable="true">
<div></div>
</div>

見た目は特に変化がないけどこうしておくと、一行目のテキストは用意されたdivに入り、二行目以降が新しく生成されたdivに入るようになる。

でもこれを使うと、要素の中身空の場合のみ表示させる:emptyが使えなくなるのでplaceholderの表示方法をJSとかで調整する必要がある。
classで擬似要素の有無を制御しつつ、要素に対してキー入力があった場合に中のテキストを取得→空ならclassを付けてplaceholderを表示する、とかね。

IE謎の空白文字問題

一度入力した文字を全て消した後に、入力エリアに半角スペースが幾つか出現する自体が発生。
どうやらインデントに使用していた半角スペースが出てくるらしく、contenteditable="true"に子要素をもたせる場合はインデントを付けないようにしないとおかしなことになる。

<div contenteditable="true"><div></div></div>