« Kanasan.JS開催のお知らせと注意 | メイン | 続・全てのtextareaを自動的にリサイズするJavaScriptとGreasemonkey »

全てのtextareaを自動的にリサイズするJavaScriptとGreasemonkey

「やるならここまで徹底して実装しようよ」という私は変態ですか?
そうですか。
codeは下の方。
デモは次のurl。
ついでにGreasemonkeyのuserscriptも。
難点はstyleの指定されていないtextareaなら全て自動的にリサイズしてしまう事。
修正するなら、addAutoResizeTextareaに全てのtextareaを渡さずに、任意のものを渡すようにすればいいってことで...。
2008/05/21 追記
大事なこと書き忘れてた。
元ネタは縦方向にのみだけど、こちらは横方向にも対応。
半角全角も判定している。
0x100移行にある"見た目が"半角の文字には残念ながら未対応。
そこまできちんとやるならフォントのグリフにまで手を伸ばさなくちゃならないけど、非現実的なのでこのままで。
2008/05/22 追記
はてなブックマークコメントで、id:rokuroxに「全角文字の対応がいまいちだから全角文字を大量に入力すると横幅がひどく長くなりますね」と突っ込まれましたが、これ全角であろうが半角であろうが際限なく横に伸びて行きます。
そう動くように作りました。
横だけでなく、下にもいつまでも広がっていきます。
元ネタの実装も際限ないです。
もし、制限を設けたいのであれば、
Math.max(Math.min(colsAndRows.cols+1,maxX),minX);
とすることで対応可能です。
但し、minX<=maxXであることを確認しなければ思わぬ動きをするので注意が必要です。
minX>maxXの時はswapするようにすれば良いかもしれません。
また、現状ではOperaに対応していません。
Operaに対応するには、addEventListenerの第三をfalseにする必要があります。
IMEからの場合、入力中だけでなく確定時にもkeyupイベントが発生しません。
resize処理は、focusが外れた時に発生するchangeイベントまでまたなくてはいけません。
このため、timer系の処理を追加し、定期的に処理する必要があります。
定期的な処理が全てのtextareaに対して行われるのは重くなる原因ですので、次のような実装が理想だと思います。
毎回resize処理を走らせるのではなく、前回走った時と内包する文字列が同一かどうか判定し、同一でない時初めてresize処理を行うようにします。
更に、いつでもtimer処理が走っているのも変ですので、focusイベント発生時にtimerを走らせ、blurイベント発生時にtimerを破棄するようにします。
以上、全て実装すればLibraryとしての価値が出てくるかと思います。
2008/05/23 追記
追記しようとしていた内容があまりにも長くなり過ぎたので別エントリーにしました。
(function(){
    var addEvent=
        function(element,eventName,handler){
            if(element.addEventListener){
                element.addEventListener(eventName,handler,true);
        }else{
            element.attachEvent("on"+eventName,handler);
        }
    }

addEvent(
    window,
    "load",
    function(){
        var getLength=
            function(str){
                return str.length+str.replace(/[\x0-\xff]/g,"").length;
            }
        var sort=
            (function(getLength){
                var _getLength=getLength;
                return function(a,b){
                    return _getLength(a)-_getLength(b);
                }
            })(getLength);
        var getColsAndRows=
            function(str){
                var ary=str.
                        replace(/\r\n/ig,"\n").
                        replace(/\r/ig,"\n").
                        split("\n");
                ary.sort(sort);
                return {
                    "cols":getLength(ary[ary.length-1]),
                    "rows":ary.length
                };
            }
        var resizeTextarea=
            function(){
                var colsAndRows=getColsAndRows(this.value);
                this.setAttribute("cols",colsAndRows.cols+1);
                this.setAttribute("rows",colsAndRows.rows+1);
            }
        var resizeTextareaHandler=
            function(textarea){
                var _textarea=textarea;
                return function(){
                    resizeTextarea.call(_textarea);
                }
            }
        var addAutoResizeTextarea=
            function(textarea){
                var handler=resizeTextareaHandler(textarea);
                handler();
                addEvent(textarea,"keyup",handler);
                addEvent(textarea,"change",handler);
            }
        var addAutoResizeTextareas=
            function(){
                var textareas=
                        document.getElementsByTagName("textarea");
                for(var i=0;i<textareas.length;i++){
                    addAutoResizeTextarea(textareas[i]);
                }
            }
        addAutoResizeTextareas();
    }
);
})();

コメント (1)

parion [TypeKey Profile Page]:

ども。

デモをIE,FireFox2,Opera(ローカルにコピペしてaddEventListenerの第三をfalseってのも試した),GoogleChromeで試しましたが、
日本語変換中に対応してるのはIEだけでした。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

Google

タグ クラウド