iPhoneのwebアプリをsencha touchでつくっていて、非常にこまったのが、テキストエリアの取り扱い。
普通にtextareaを置くだけなら、デフォルト動作が発動するので、問題はないのですが、sencha-touchをつかってつくっているといろいろと動作不具合がでてきます。
問題点は
- テキストエリアの中で行数がふえすぎると、テキストエリアの内部をスクロールさせるすべがない。
- テキストエリアがおおきく、スクロールして、テキストエリアのトップが上部にはみ出している場合に、文字入力しようとするとアドレスバーがはいってきて、編集できない。
といった問題があります。
というわけで、僕の対処の仕方です。
まず、前者の問題行数が増えすぎて、はみ出るとスクロールできない。
→よって行数がふえたら、テキストエリアを大きくしてやればよい。
textareaでkeyup eventを監視して、行数が増えた場合は大きくしてやればいい。
sencha touchで追加したコンポーネントは直接IDを取得したりする方法がないので、textareaの大きさ変更はtextareaのスタイルシートを書き換えることで実施しています。
テキストエリアのcss設定
textarea {
height: 100;
}
// cssの要素の大きさを変更するjavascript関数
function changeTextareaHeight(value) {
var css_list = document.styleSheets;
if(css_list) for (var i = 0;i < css_list.length;i ++) {
var rule_list = (css_list[i].cssRules) ? css_list[i].cssRules : css_list[i].rules;
if(rule_list == null) {
continue;
}
for(var ii = 0;ii < rule_list.length;ii ++) {
if(rule_list[ii].selectorText == 'textarea') {
with(rule_list[ii].style) {
// fontSize = "50%";
height = value + "px";
}
}
}
}
}
// keyupのイベント
keyup: function(target, event) {
// 入力文字の文字列数を確認して、改行にあわせて、パネルのサイズを変更する。
var data = target.getValue();
var matches = data.match(/[\n|\r\n]/g);
var num = 0;
if(matches instanceof Array) {
num = matches.length;
}
if(this.lineNum == num) {
return;
}
this.lineNum = num;
// パネルの高さx2+文字の高さx改行数
// これをtextareaのサイズにして調整すればOK
changeTextareaHeight(App.views.viewport.height + num * 24);
}
これで行数がふえればそのままテキストエリアがどんどん大きくなっていきます。
一応問題点もあり、文字が長過ぎて改行文字抜きに改行されてしまった場合。
上記の正規表現からすると、改行とカウントされないのでずれが発生します。
さて2つ目の問題、アドレスバー等がはいってきて困る問題の対処です。
アドレスバーがでてきてしまう問題は、テキストエリアにフォーカスがあたったときに、テキストエリアのちょうど上部の端までwindowをスクロールしてやれば大丈夫みたいです。
よってfocusのイベントでwindow.scrollToを実行します。
focus: function(target, event) {
var toolbar = Ext.getCmp('editToolbar');
this.toolbarHeight = toolbar.getHeight();
window.scrollTo(0,this.toolbarHeight);
},
今回のwebアプリのサンプル(chrome safari iphoneにて動作確認済み)
ではでは〜