web-dev-qa-db-ja.com

テキストエリアのイベントのサイズを変更しますか?

Firefoxの現在のバージョンとChromeは、_<textarea>_ボックスのサイズを変更するドラッグハンドラを含みます。サイズ変更イベントをキャプチャする必要があります。jQueryのresize()イベント、しかし動作しません!

通常のonResizeイベントも試しましたが、結果は同じです。 JSFiddleで試すことができます

キャプチャする方法はありますか?

45
metrobalderas

Resizeイベントを発行する前に、まずtextareaのサイズを変更可能にする必要があります。 jQuery UI resizable() を使用してそれを行うことができ、その内部でresizeイベントを呼び出すことができます。

$("textarea").resizable({
    resize: function() {
        $("body").append("<pre>resized!</pre>");
    }
});

http://jsfiddle.net/HhSYG/1/ で動作例を確認してください

2
Hussein

これは古い質問ですが、他の誰かがIRCで同じ質問をしていたので、ここで解決することにしました: http://jsfiddle.net/vol7ron/Z7HDn/

Chromeはサイズ変更イベントをキャプチャせず、Chromeはmousedownをキャプチャしません。そのため、init状態を設定し、mouseupで変更を処理する必要があります。

jQuery(document).ready(function(){
   var $textareas = jQuery('textarea');

   // store init (default) state   
   $textareas.data('x', $textareas.outerWidth());
   $textareas.data('y', $textareas.outerHeight()); 

   $textareas.mouseup(function(){

      var $this = jQuery(this);

      if (  $this.outerWidth()  != $this.data('x') 
         || $this.outerHeight() != $this.data('y') )
      {
          // Resize Action Here
          alert( $this.outerWidth()  + ' - ' + $this.data('x') + '\n' 
               + $this.outerHeight() + ' - ' + $this.data('y')
               );
      }

      // store new height/width
      $this.data('x', $this.outerWidth());
      $this.data('y', $this.outerHeight()); 
   });

});

HTML

<textarea></textarea>
<textarea></textarea>

注:

  1. フセインが行ったように、サイズ変更可能な独自のアタッチが可能ですが、元のコードが必要な場合は、上記のコードを使用できます
  2. ブライアン・ダウニングが述べているように、これはマウスがテキストエリアの上にあるときにマウスアップするときに機能します。ただし、ブラウザが最大化されておらず、ブラウザの範囲を超えてドラッグし続ける場合や、resize:vertical動きをロックします。

    より高度なものを使用するには、他のリスナー、おそらくキュースキャナーとインターバルスキャナーを追加する必要があります。または、jQueryのサイズ変更ができると思うのでmousemoveを使用します-質問はパフォーマンスとポーランド語をどれだけ評価しますか?


更新:以来、ブラウザのUIに変更がありました。ここで、コーナーをダブルクリックすると、テキストボックスがデフォルトのサイズに縮小される場合があります。そのため、このイベントの前後にも変更をキャプチャする必要があります。

41
vol7ron

これの新しい標準は、Resize Observer apiです。実験的なWebプラットフォーム機能フラグの背後にあるChrome Dev 54で利用可能です。

function outputsize() {
 width.value = textbox.offsetWidth
 height.value = textbox.offsetHeight
}
outputsize()

new ResizeObserver(outputsize).observe(textbox)
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me.</textarea>

または、Mutation Observerを使用して、Firefoxのスタイル属性の変更を検出し、Chrome 54.

function outputsize() {
 width.value = textbox.offsetWidth
 height.value = textbox.offsetHeight
}
outputsize()

new MutationObserver(outputsize).observe(textbox, {
 attributes: true, attributeFilter: [ "style" ]
})
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me.</textarea>

オブザーバーのサイズ変更

仕様: https://wicg.github.io/ResizeObserver

ポリフィル: https://github.com/pelotoncycle/resize-observer

Chromeの問題: https://crbug.com/612962

Chromeフラグ:chrome:// flags /#enable-experimental-web-platform-features

Firefoxの問題: https://bugzil.la/1272409

Safariの問題: http://wkb.ug/15774

15
Daniel Herr

Vol7ronの答えを少し混ぜて、「Resize Action Here」を通常の「resize」イベントの単純なトリガーに置き換えただけなので、「通常どおり」resizeイベントに何でもしたいことができます。

$(document).ready(function(){
    $('textarea').bind('mouseup mousemove',function(){
        if(this.oldwidth  === null){this.oldwidth  = this.style.width;}
        if(this.oldheight === null){this.oldheight = this.style.height;}
        if(this.style.width != this.oldwidth || this.style.height != this.oldheight){
            $(this).resize();
            this.oldwidth  = this.style.width;
            this.oldheight = this.style.height;
        }
    });
});

Mousemoveイベントを追加したので、サイズ変更中にマウスをドラッグするとサイズ変更も発生しますが、マウスを移動すると頻繁に発生することに注意してください。

この場合、サイズ変更イベントを実際にトリガーまたは処理する際に少し遅延を入れたい場合があります。上記を置き換えます。

$(this).resize();

で:

if(this.resize_timeout){clearTimeout(this.resize_timeout);}
this.resize_timeout = setTimeout(function(){$(this).resize();},100);

使用例では、2番目のテキストエリアを最初のテキストエリアで拡大縮小します。

$('textarea').eq(0).resize(function(){
    var $ta2 = $('textarea').eq(1);
    $('textarea').eq(1).css('width',$ta2.css('width')).css('height',$ta2.css('height'));
});
7
MoonLite

別の方法は、textareaのmouseupイベントにバインドすることです。その後、サイズが変更されたかどうかを確認できます。

6
Guy

Textareaのサイズ変更イベントは存在しません。

サイズ変更可能なjQueryPluginはネイティブに見えないため、代替を使用する必要があります。

エミュレートする1​​つの方法は、mousedown/clickイベントを使用することです。リアルタイムのイベントトリガーが必要な場合は、次のようにできます。

2013年11月11日更新:

// This fiddle shows how to simulate a resize event on a
// textarea
// Tested with Firefox 16-25 Linux / Windows
// Chrome 24-30 Linux / Windows

var textareaResize = function(source, dest) {
    var resizeInt = null;

    // the handler function
    var resizeEvent = function() {
        dest.outerWidth( source.outerWidth() );
        dest.outerHeight(source.outerHeight());
    };

    // This provides a "real-time" (actually 15 fps)
    // event, while resizing.
    // Unfortunately, mousedown is not fired on Chrome when
    // clicking on the resize area, so the real-time effect
    // does not work under Chrome.
    source.on("mousedown", function(e) {
        resizeInt = setInterval(resizeEvent, 1000/15);
    });

    // The mouseup event stops the interval,
    // then call the resize event one last time.
    // We listen for the whole window because in some cases,
    // the mouse pointer may be on the outside of the textarea.
    $(window).on("mouseup", function(e) {
        if (resizeInt !== null) {
            clearInterval(resizeInt);
        }
        resizeEvent();
    });
};

textareaResize($("#input"), $("#output"));

デモ: http://jsfiddle.net/gbouthenot/D2bZd/

2
megar

FireFoxはテキストエリアでMutationObserverイベントをサポートするようになり、これは非常にうまく機能しているようです。 Chrome残念ながらまだ回避策が必要です。

このページの他の回答に基づいて、textareaのサイズが変更されたときにウィンドウサイズ変更イベントをトリガーする、リファクタリングおよび更新されたバージョンがあります。

また、textareaがフレームより大きくなったことを検出するためにiFrameで必要なウィンドウから出るマウスのイベントリスナーも追加しました。

(function(textAreaChanged){
    function store(){
        this.x = this.offsetWidth;
        this.y = this.offsetHeight;
    }

    function textAreaEvent(){
        if (this.offsetWidth !== this.x || this.offsetHeight !== this.y) {
            textAreaChanged();
            store.call(this);
        }
    }

    $('textarea').each(store).on('mouseup mouseout',textAreaEvent);

    $(window).on('mouseup',textAreaEvent);

})(function(){
    $(window).trigger('resize');
});

IE9以降では、jQueryなしでも同じことができます。

(function(textAreaChanged){
    function store(){
        this.x = this.offsetWidth;
        this.y = this.offsetHeight;
    }

    function textAreaEvent(){
        if (this.offsetWidth !== this.x || this.offsetHeight !== this.y) {
            textAreaChanged();
            store.call(this);
        }
    }

    Array.prototype.forEach.call(
        document.querySelectorAll('textarea'),
        function (el){
            el.addEventListener('mouseup',   textAreaEvent);
            el.addEventListener('mouseout',  textAreaEvent);
        }
    );

    window.addEventListener('mouseup',textAreaEvent)

})(function(){
    //trigger window resize
    var event = document.createEvent('Events');
    event.initEvent('resize', true, false);
    window.dispatchEvent(event);
});
1
David Bradshaw