2017年3月12日日曜日

textareaをブラウザいっぱいに広げる WideArea をfixしてみる

textareaをブラウザいっぱいに広げる切り替えができる軽量スクリプトに WideAreaというのがあります。
手軽に実装できて、非常に便利です。

だがしかし、長い間メンテさていなく、不具合がいくつか残ったままです。
まぁ小さなスクリプトなので、さくっと手直しして、実用に耐えられる物にしてみます。
ただし、jQuery前提の箇所もあります。
それと、好みによる改造ポイントも。

■拡大ボタン表示位置を決めるロジックが動いていない
公式トップにあるデモを見ての通り、IEでもChromeでもEdgeでもダメです。
昔の古いブラウザではおそらく、動いていたのでしょう。

×:offsetWidth
〇:clientWidth

ユーザー入力部分の横幅は clientWidth で取得しなければなりません。
offsetWidthですと、一番外側のボーダーまで含まれてしまいます。

これだけだと、スクロールバーが無い時にアイコンが点滅っぽい状態になります。
タイマーでループ処理されているのですが、最後の条件文が正しくありません。
タイマーを使う事自体が間違っているというのは置いておきます。

×:(oldPosition.left - currentTextareaPosition.width + 21) != currentTextareaPosition.left
〇:oldPosition.width != currentTextareaPosition.width

■拡大時に、スクロールバーが二重化
スクロールの発生するページで使うと、ページのスクロールとtextareaのスクロールで2重になります。

拡大時はページのスクロールバーを非表示にしてあげましょう。

・拡大移行処理
関数 _enableFullScreen() 内 document.body.appendChild()実行直前に追加

$("body").css("overflow","hidden");

突然jQueryでごめんなさい。

・通常サイズ移行処理
関数 _disableFullScreen() 内 overlayLayer.parentNode.removeChild()実行直後に追加

$("body").css("overflow","auto");

これで綺麗に動きます。

■ヘンテコなバックアップ機能がある
複数ページに設置すると、動きません。(他ページのバックアップで上書きされる)
フォームに初期値が入っていると、機能しません。(バックアップで上書きされる)

_saveToStorage()と_getFromStorage()の中身を空にすれば、機能を削除できます。

■拡大ボタンの表示に問題が起きる場合等
タイマーを使ってるので相性問題が出やすいです。アイコン追従がカクカクですしね。
汎用的にするなら、タイマーを使わない実装がよろしいです。

textareaのサイズ変更時に処理したいなら、タイマー部分を削除して
$(document).on('mouseup mousemove change', 'textarea[' + this._options.wideAreaAttr + '=\'enable\']', function() {
var wideAreaIcons = document.getElementById("widearea-" + $(this).attr("data-widearea-id"));
_renewIconsPosition($(this)[0], wideAreaIcons);
});
サイズ変更中は mouemove で拾えます。
変更完了は、mouseup で拾えます。
スクロールバーが出たり消えたりは、change で拾えます。

他の方法としては、jQuery UIの resizable を使う方法もあります。
これのイベントに resize があります。

上記のみだと、テキストエリアの位置そのものが動的に変化した場合にボタンがズレます。
CSSで absolute(絶対値) 指定しているのが原因です。
.widearea-icons を position: relative; にしましょう。
これにより下部に余白ができてしまうので
.widearea-wrapper {height: 0;} を追加します。

js側の修正は
- document.body.appendChild(wideAreaWrapper);
+ $(currentTextArea).after(wideAreaWrapper);
これでボタン要素がテキストエリアに追従するようになります。

位置修正関数 _renewIconsPosition() も修正します。
iconPanel.style.left = currentTextareaPosition.width -21 + "px";
iconPanel.style.top  = "-" + currentTextareaPosition.height + "px";

これで大抵の場合はボタンがズレなくなります。レスポンシブ対応ってことです。

■拡大時に横幅固定とフォント巨大化で、拡大のメリットがあまりない問題
拡大しても、文字が大きくなるだけで一度に表示できる量が変わらなじゃんって場合。

CSSの max-width を削除すれば、名実共にフルサイズボックス化。
font-sizeとline-heightも削除か変更して、快適に。